Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added __pycache__/analytics.cpython-312.pyc
Binary file not shown.
71 changes: 64 additions & 7 deletions analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ def filter_sales_above_threshold(sales: list, threshold: int):
- Use a loop or list comprehension
"""
# TODO: Write your code here
pass
above_treshold = []
if len(sales) == 0:
return above_treshold
else:
for i in sales:
if i > threshold:
above_treshold.append(i)
return above_treshold
Comment on lines +20 to +27
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Typo in variable name: 'treshold' should be 'threshold'.

Suggested change
above_treshold = []
if len(sales) == 0:
return above_treshold
else:
for i in sales:
if i > threshold:
above_treshold.append(i)
return above_treshold
above_threshold = []
if len(sales) == 0:
return above_threshold
else:
for i in sales:
if i > threshold:
above_threshold.append(i)
return above_threshold

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +27
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Typo in variable name: 'treshold' should be 'threshold'. This misspelling is used throughout the function.

Suggested change
above_treshold = []
if len(sales) == 0:
return above_treshold
else:
for i in sales:
if i > threshold:
above_treshold.append(i)
return above_treshold
above_threshold = []
if len(sales) == 0:
return above_threshold
else:
for i in sales:
if i > threshold:
above_threshold.append(i)
return above_threshold

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +27
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Typo in variable name: 'treshold' should be 'threshold'.

Suggested change
above_treshold = []
if len(sales) == 0:
return above_treshold
else:
for i in sales:
if i > threshold:
above_treshold.append(i)
return above_treshold
above_threshold = []
if len(sales) == 0:
return above_threshold
else:
for i in sales:
if i > threshold:
above_threshold.append(i)
return above_threshold

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +27
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Typo in variable name: 'treshold' should be 'threshold'.

Suggested change
above_treshold = []
if len(sales) == 0:
return above_treshold
else:
for i in sales:
if i > threshold:
above_treshold.append(i)
return above_treshold
above_threshold = []
if len(sales) == 0:
return above_threshold
else:
for i in sales:
if i > threshold:
above_threshold.append(i)
return above_threshold

Copilot uses AI. Check for mistakes.


def count_product_codes(codes: list, prefix: str):
Expand All @@ -33,8 +40,11 @@ def count_product_codes(codes: list, prefix: str):
- Return 0 if no matches found
"""
# TODO: Write your code here
pass

count = 0
for string in codes:
if prefix in string:
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The logic for checking if a product code starts with the prefix is incorrect. Using in checks if the prefix appears anywhere in the string, not just at the start. Use string.startswith(prefix) instead.

Example: With current code, count_product_codes(["XPROD-001"], "PROD") would incorrectly return 1.

Suggested change
if prefix in string:
if string.startswith(prefix):

Copilot uses AI. Check for mistakes.
count += 1
return count

def calculate_moving_average(numbers: list, window_size: int):
"""
Expand All @@ -51,7 +61,19 @@ def calculate_moving_average(numbers: list, window_size: int):
- Return 0.0 for empty list
"""
# TODO: Write your code here
pass
count = 0
if len(numbers) == 0:
return 0.0
elif len(numbers) >= 3:
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The hardcoded check len(numbers) >= 3 is incorrect. The function should work with any window_size, not just 3. This condition should check against window_size instead.

Suggested change
elif len(numbers) >= 3:
elif len(numbers) >= window_size:

Copilot uses AI. Check for mistakes.
for i in range(-window_size, 0):
count += numbers[i]
average = count/window_size
return average
else:
for i in numbers:
count += i
average = count/len(numbers)
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The variable average is being recalculated on every iteration of the loop instead of once after the loop completes. Move line 75 outside the loop (dedent it to align with the return statement).

Suggested change
average = count/len(numbers)
average = count/len(numbers)

Copilot uses AI. Check for mistakes.
Comment on lines +69 to +75
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The variable average is being recalculated on every iteration of the loop instead of once after the loop completes. Move line 70 outside the loop (dedent it to align with the return statement).

Suggested change
count += numbers[i]
average = count/window_size
return average
else:
for i in numbers:
count += i
average = count/len(numbers)
count += numbers[i]
average = count / window_size
return average
else:
for i in numbers:
count += i
average = count / len(numbers)

Copilot uses AI. Check for mistakes.
return average


# ==========================================
Expand All @@ -72,7 +94,16 @@ def get_top_seller(sales_data: dict):
- If there's a tie, return the name that appears first alphabetically
"""
# TODO: Write your code here
pass
tie = []
if len(sales_data) == 0:
return f"No Data"
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Unnecessary f-string formatting. The return value is just a plain string with no variables, so use "No Data" instead of f"No Data".

Suggested change
return f"No Data"
return "No Data"

Copilot uses AI. Check for mistakes.
else:
max_sale = max(sales_data.values())
for name, sale in sales_data.items():
if sale == max_sale:
tie.append(name)
#name = [name for name in tie]
return sorted(tie)[0]


def merge_inventory(warehouse_a: dict, warehouse_b: dict):
Expand All @@ -93,7 +124,19 @@ def merge_inventory(warehouse_a: dict, warehouse_b: dict):
- Do NOT modify the original dictionaries
"""
# TODO: Write your code here
pass
new_warehouse = {}
if warehouse_a and warehouse_b:
return new_warehouse
else:
for a in warehouse_a:
for b in warehouse_b:
if a == b:
new_warehouse[a] = warehouse_a[a] + warehouse_b[b]
else:
new_warehouse[a] = warehouse_a[a]
new_warehouse[b] = warehouse_b[b]
Comment on lines +128 to +137
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The nested loop logic is incorrect for merging dictionaries. This creates a Cartesian product of keys, leading to incorrect results. For example, products unique to one warehouse would be added multiple times. Use new_warehouse.update() or iterate through each warehouse separately to properly merge the inventories.

Suggested change
if warehouse_a and warehouse_b:
return new_warehouse
else:
for a in warehouse_a:
for b in warehouse_b:
if a == b:
new_warehouse[a] = warehouse_a[a] + warehouse_b[b]
else:
new_warehouse[a] = warehouse_a[a]
new_warehouse[b] = warehouse_b[b]
if not warehouse_a and not warehouse_b:
return new_warehouse
else:
all_keys = set(warehouse_a.keys()) | set(warehouse_b.keys())
for key in all_keys:
new_warehouse[key] = warehouse_a.get(key, 0) + warehouse_b.get(key, 0)

Copilot uses AI. Check for mistakes.
return new_warehouse
Comment on lines +128 to +138
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The logic is inverted. The function should return an empty dictionary when both inputs are empty (both warehouse_a and warehouse_b are empty/falsy), but the current condition if warehouse_a and warehouse_b returns empty when BOTH are non-empty. This should be if not warehouse_a and not warehouse_b:.

Suggested change
if warehouse_a and warehouse_b:
return new_warehouse
else:
for a in warehouse_a:
for b in warehouse_b:
if a == b:
new_warehouse[a] = warehouse_a[a] + warehouse_b[b]
else:
new_warehouse[a] = warehouse_a[a]
new_warehouse[b] = warehouse_b[b]
return new_warehouse
if not warehouse_a and not warehouse_b:
return new_warehouse
else:
all_keys = set(warehouse_a.keys()) | set(warehouse_b.keys())
for key in all_keys:
new_warehouse[key] = warehouse_a.get(key, 0) + warehouse_b.get(key, 0)
return new_warehouse

Copilot uses AI. Check for mistakes.



# ==========================================
Expand Down Expand Up @@ -136,4 +179,18 @@ def check_inventory_status(stock_level: int, reorder_point: int, max_capacity: i
- All other cases: return "OPTIMAL"
"""
# TODO: Write your code here
pass
if stock_level < 0 or reorder_point < 0 or max_capacity < 0 or daily_sales < 0:
return f"Invalid Input"
elif stock_level > max_capacity:
return f"Invalid Input"
elif stock_level > (max_capacity * 0.9):
f"OVERSTOCKED"
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Missing return statement. This condition checks if stock is overstocked but doesn't return the value. Add return before the f-string: return f"OVERSTOCKED".

Suggested change
f"OVERSTOCKED"
return f"OVERSTOCKED"

Copilot uses AI. Check for mistakes.
elif stock_level < (reorder_point*0.5):
return f"CRITICAL"
elif stock_level <= reorder_point:
return f"REORDER"
elif (daily_sales > 0) and (stock_level < 7 or daily_sales < 7):
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The logic for detecting low stock is incorrect. According to the requirements (line 106 in docstring), it should be stock_level / daily_sales < 7, but this code checks stock_level < 7 or daily_sales < 7. The correct condition should be: if daily_sales > 0 and stock_level / daily_sales < 7:.

Suggested change
elif (daily_sales > 0) and (stock_level < 7 or daily_sales < 7):
elif (daily_sales > 0) and (stock_level / daily_sales < 7):

Copilot uses AI. Check for mistakes.
return F"LOW STOCK"
else:
return F"OPTIMAL"
Comment on lines +193 to +195
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Inconsistent string formatting. Use lowercase 'f' for f-strings consistently throughout the file (other return statements use lowercase 'f').

Suggested change
return F"LOW STOCK"
else:
return F"OPTIMAL"
return f"LOW STOCK"
else:
return f"OPTIMAL"

Copilot uses AI. Check for mistakes.
Comment on lines +183 to +195
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Unnecessary f-string formatting. The return value is just a plain string with no variables, so use "Invalid Input" instead of f"Invalid Input".

Suggested change
return f"Invalid Input"
elif stock_level > max_capacity:
return f"Invalid Input"
elif stock_level > (max_capacity * 0.9):
f"OVERSTOCKED"
elif stock_level < (reorder_point*0.5):
return f"CRITICAL"
elif stock_level <= reorder_point:
return f"REORDER"
elif (daily_sales > 0) and (stock_level < 7 or daily_sales < 7):
return F"LOW STOCK"
else:
return F"OPTIMAL"
return "Invalid Input"
elif stock_level > max_capacity:
return "Invalid Input"
elif stock_level > (max_capacity * 0.9):
return "OVERSTOCKED"
elif stock_level < (reorder_point*0.5):
return "CRITICAL"
elif stock_level <= reorder_point:
return "REORDER"
elif (daily_sales > 0) and (stock_level < 7 or daily_sales < 7):
return "LOW STOCK"
else:
return "OPTIMAL"

Copilot uses AI. Check for mistakes.
Comment on lines +183 to +195
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Unnecessary f-string formatting. The return value is just a plain string with no variables, so use "CRITICAL" instead of f"CRITICAL".

Suggested change
return f"Invalid Input"
elif stock_level > max_capacity:
return f"Invalid Input"
elif stock_level > (max_capacity * 0.9):
f"OVERSTOCKED"
elif stock_level < (reorder_point*0.5):
return f"CRITICAL"
elif stock_level <= reorder_point:
return f"REORDER"
elif (daily_sales > 0) and (stock_level < 7 or daily_sales < 7):
return F"LOW STOCK"
else:
return F"OPTIMAL"
return "Invalid Input"
elif stock_level > max_capacity:
return "Invalid Input"
elif stock_level > (max_capacity * 0.9):
return "OVERSTOCKED"
elif stock_level < (reorder_point*0.5):
return "CRITICAL"
elif stock_level <= reorder_point:
return "REORDER"
elif (daily_sales > 0) and (stock_level < 7 or daily_sales < 7):
return "LOW STOCK"
else:
return "OPTIMAL"

Copilot uses AI. Check for mistakes.
Comment on lines +183 to +195
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Unnecessary f-string formatting. The return value is just a plain string with no variables, so use "Invalid Input" instead of f"Invalid Input".

Suggested change
return f"Invalid Input"
elif stock_level > max_capacity:
return f"Invalid Input"
elif stock_level > (max_capacity * 0.9):
f"OVERSTOCKED"
elif stock_level < (reorder_point*0.5):
return f"CRITICAL"
elif stock_level <= reorder_point:
return f"REORDER"
elif (daily_sales > 0) and (stock_level < 7 or daily_sales < 7):
return F"LOW STOCK"
else:
return F"OPTIMAL"
return "Invalid Input"
elif stock_level > max_capacity:
return "Invalid Input"
elif stock_level > (max_capacity * 0.9):
return "OVERSTOCKED"
elif stock_level < (reorder_point*0.5):
return "CRITICAL"
elif stock_level <= reorder_point:
return "REORDER"
elif (daily_sales > 0) and (stock_level < 7 or daily_sales < 7):
return "LOW STOCK"
else:
return "OPTIMAL"

Copilot uses AI. Check for mistakes.
Comment on lines +183 to +195
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Unnecessary f-string formatting. The return value is just a plain string with no variables, so use "REORDER" instead of f"REORDER".

Suggested change
return f"Invalid Input"
elif stock_level > max_capacity:
return f"Invalid Input"
elif stock_level > (max_capacity * 0.9):
f"OVERSTOCKED"
elif stock_level < (reorder_point*0.5):
return f"CRITICAL"
elif stock_level <= reorder_point:
return f"REORDER"
elif (daily_sales > 0) and (stock_level < 7 or daily_sales < 7):
return F"LOW STOCK"
else:
return F"OPTIMAL"
return "Invalid Input"
elif stock_level > max_capacity:
return "Invalid Input"
elif stock_level > (max_capacity * 0.9):
return "OVERSTOCKED"
elif stock_level < (reorder_point*0.5):
return "CRITICAL"
elif stock_level <= reorder_point:
return "REORDER"
elif (daily_sales > 0) and (stock_level < 7 or daily_sales < 7):
return "LOW STOCK"
else:
return "OPTIMAL"

Copilot uses AI. Check for mistakes.
Comment on lines +193 to +195
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Inconsistent string formatting. Use lowercase 'f' for f-strings consistently throughout the file (lines 183, 185, 189, 191 use lowercase 'f', but this line uses uppercase 'F').

Suggested change
return F"LOW STOCK"
else:
return F"OPTIMAL"
return f"LOW STOCK"
else:
return f"OPTIMAL"

Copilot uses AI. Check for mistakes.

37 changes: 37 additions & 0 deletions test_inventory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import unittest
from analytics import check_inventory_status
class TestInventory(unittest.TestCase):
def test_q6_inventory_invalid_input(self):
print("Grading Q6: Inventory Status (Invalid Input)...")
self.assertEqual(check_inventory_status(-10, 50, 100, 10), "Invalid Input")
self.assertEqual(check_inventory_status(50, -10, 100, 10), "Invalid Input")
self.assertEqual(check_inventory_status(50, 50, -100, 10), "Invalid Input")
self.assertEqual(check_inventory_status(50, 50, 100, -10), "Invalid Input")
self.assertEqual(check_inventory_status(150, 50, 100, 10), "Invalid Input")

def test_q6_inventory_overstocked(self):
print("Grading Q6: Inventory Status (Overstocked)...")
self.assertEqual(check_inventory_status(95, 50, 100, 10), "OVERSTOCKED")
self.assertEqual(check_inventory_status(91, 50, 100, 10), "OVERSTOCKED")

def test_q6_inventory_critical(self):
print("Grading Q6: Inventory Status (Critical)...")
self.assertEqual(check_inventory_status(20, 50, 100, 10), "CRITICAL")
self.assertEqual(check_inventory_status(10, 100, 200, 5), "CRITICAL")

def test_q6_inventory_reorder(self):
print("Grading Q6: Inventory Status (Reorder)...")
self.assertEqual(check_inventory_status(50, 50, 100, 5), "REORDER")
self.assertEqual(check_inventory_status(45, 50, 100, 5), "REORDER")

def test_q6_inventory_low_stock(self):
print("Grading Q6: Inventory Status (Low Stock)...")
self.assertEqual(check_inventory_status(60, 50, 100, 10), "LOW STOCK")
self.assertEqual(check_inventory_status(69, 50, 100, 10), "LOW STOCK")

def test_q6_inventory_optimal(self):
print("Grading Q6: Inventory Status (Optimal)...")
self.assertEqual(check_inventory_status(70, 50, 100, 10), "OPTIMAL")
self.assertEqual(check_inventory_status(80, 50, 100, 5), "OPTIMAL")
# Zero daily sales should not trigger low stock
self.assertEqual(check_inventory_status(60, 50, 100, 0), "OPTIMAL")