diff --git a/.github/workflows/run_test.yml b/.github/workflows/run_test.yml new file mode 100644 index 00000000..e8f35ba0 --- /dev/null +++ b/.github/workflows/run_test.yml @@ -0,0 +1,32 @@ +name: simple_calculator unit test + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10"] + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Lint with Ruff + run: | + pip install ruff + ruff --format=github --target-version=py310 . + continue-on-error: true + - name: Test with pytest + run: | + coverage run -m pytest tests/tests_1b.py tests/tests_1c.py tests/tests_1d.py -v -s + - name: Generate Coverage Report + run: | + coverage report -m \ No newline at end of file diff --git a/labs/lab_1/lab_1a.py b/labs/lab_1/lab_1a.py index 9d15ec83..cd76109c 100644 --- a/labs/lab_1/lab_1a.py +++ b/labs/lab_1/lab_1a.py @@ -3,14 +3,17 @@ The first lab in the BWSI CSS course. To complete this lab, fill out the variable on line 10 with your name. Then, save the code, add it to the staging area, and commit it to the Git tree. + +This is to simulate a change made on a robot: robot_speed = 8 # m/s """ def main(): print("Hello World!") - name = "" # TODO: Insert your name between the double quotes + name = "Arnav Mittal" # TODO: Insert your name between the double quotes print(f"{name}, Welcome to the CSS course!") + print(f"I'm a sophomore from Texas! I dream of being a particle physicist.") if __name__ == "__main__": main() diff --git a/labs/lab_1/lab_1b.py b/labs/lab_1/lab_1b.py index e58dd957..a2472c30 100644 --- a/labs/lab_1/lab_1b.py +++ b/labs/lab_1/lab_1b.py @@ -36,16 +36,30 @@ def simple_calculator(operation: str, num1: float, num2: float) -> float: raise ValueError("Cannot divide by zero.") else: raise ValueError("Invalid operation. Please choose from 'add', 'subtract', 'multiply', or 'divide'.") + +def request_sanitized_number(prompt: str) -> float: + while True: + try: + number = float(input(prompt)) + return number + except ValueError: + print("Invalid input. Please enter a valid number.") + +def request_sanitized_operation(prompt: str) -> str: + while True: + operation = input(prompt).strip().lower() + if operation in ["add", "subtract", "multiply", "divide"]: + return operation + print("Invalid input. Please enter add, subtract, multiply, or divide.") def main(): print(f"===== Simple Calculator =====") # Ask the user for sample input - num1 = float(input("Enter the first number: ")) - num2 = float(input("Enter the second number: ")) - operation = input("Enter the operation (add, subtract, multiply, divide): ").strip().lower() - + num1 = request_sanitized_number("Enter the first number: ") + num2 = request_sanitized_number("Enter the second number: ") + operation = request_sanitized_operation("Enter the operation (add, subtract, multiply, divide): ") # Perform the calculation and display the result result = simple_calculator(operation, num1, num2) print(f"The result of {operation}ing {num1} and {num2} is: {result}") diff --git a/labs/lab_1/lab_1c.py b/labs/lab_1/lab_1c.py index 40cf98db..44eaacd4 100644 --- a/labs/lab_1/lab_1c.py +++ b/labs/lab_1/lab_1c.py @@ -8,7 +8,6 @@ Derived from LeetCode problem: https://leetcode.com/problems/maximum-subarray/ (leetcode medium) """ -# TODO: Find and resolve the bug in the following implementation. Create unit tests to verify your fix. def max_subarray_sum(nums: list[int]) -> int: """ Function that takes in a list of integers and returns the maximum sum of any contiguous subarray. @@ -19,19 +18,23 @@ def max_subarray_sum(nums: list[int]) -> int: Returns: int: The maximum sum of any contiguous subarray. """ + if len(nums) == 0: + raise ValueError("Input list cannot be empty.") - max_current = max_global = nums[0] - - for num in nums: + max_current = nums[0] + max_global = nums[0] + + for num in nums[1:]: max_current = max(num, max_current + num) - if max_current < max_global: + if max_current > max_global: max_global = max_current - + return max_global + # Example usage: def main(): - nums = [-2,1,-3,4,-1,2,1,-5,4] + nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4] result = max_subarray_sum(nums) print(f"Maximum subarray sum: {result}") diff --git a/labs/lab_1/lab_1d.py b/labs/lab_1/lab_1d.py index ade4b4a8..02a8e931 100644 --- a/labs/lab_1/lab_1d.py +++ b/labs/lab_1/lab_1d.py @@ -1,14 +1,3 @@ -""" -lab_1d.py - -Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to `target`. - -You may assume that each input would have exactly one solution, and you may not use the same element twice. - -Derived from LeetCode problem: https://leetcode.com/problems/two-sum/ (leetcode easy) -""" - -# TODO: Find and resolve the bug in the following implementation. Create unit tests to verify your fix. def two_sum(nums: list[int], target: int) -> list[int]: """ Function that takes in a list of integers and a target integer, and returns the indices of the two numbers that add up to the target. @@ -23,18 +12,8 @@ def two_sum(nums: list[int], target: int) -> list[int]: num_to_index = {} for index, num in enumerate(nums): - complement = target + num + complement = target - num if complement in num_to_index: return [num_to_index[complement], index] num_to_index[num] = index - return [] # In case there is no solution, though the problem guarantees one exists. - -# Example usage: -def main(): - nums = [2, 7, 11, 15] - target = 9 - result = two_sum(nums, target) - print(f"Indices of the two numbers that add up to {target}: {result}") - -if __name__ == "__main__": - main() \ No newline at end of file + return [] \ No newline at end of file diff --git a/tests/tests_1b.py b/tests/tests_1b.py index be6b822d..9e29a8a2 100644 --- a/tests/tests_1b.py +++ b/tests/tests_1b.py @@ -11,11 +11,13 @@ def test_addition(): assert simple_calculator("add", 5, 3) == 8 # Test for positive numbers assert simple_calculator("add", -2, 2) == 0 # Test for negative and positive number assert simple_calculator("add", 0, 0) == 0 # Test for zero addition + assert simple_calculator("add", -9, 4) == -5 def test_subtraction(): assert simple_calculator("subtract", 5, 3) == 2 # Test for positive numbers assert simple_calculator("subtract", -2, -2) == 0 # Test for negative numbers assert simple_calculator("subtract", 0, 5) == -5 # Test for zero minuend + assert simple_calculator("subtract", -9, 4) == -13 def test_multiplication(): assert simple_calculator("multiply", 5, 3) == 15 # Test for positive numbers diff --git a/tests/tests_1c.py b/tests/tests_1c.py new file mode 100644 index 00000000..60926249 --- /dev/null +++ b/tests/tests_1c.py @@ -0,0 +1,37 @@ +""" +tests_1c.py + +Unit tests for max_subarray_sum in lab_1c.py. +""" + +import pytest +from labs.lab_1.lab_1c import max_subarray_sum + + +def test_typical_case(): + assert max_subarray_sum([-2, 1, -3, 4, -1, 2, 1, -5, 4]) == 6 + + +def test_single_element_positive(): + assert max_subarray_sum([5]) == 5 + + +def test_single_element_negative(): + assert max_subarray_sum([-7]) == -7 + + +def test_all_positive(): + assert max_subarray_sum([1, 2, 3, 4]) == 10 + + +def test_all_negative(): + assert max_subarray_sum([-8, -3, -6, -2, -5, -4]) == -2 + + +def test_contains_zero(): + assert max_subarray_sum([0, -1, 0, 2, 3]) == 5 + + +def test_empty_list(): + with pytest.raises(ValueError, match="Input list cannot be empty."): + max_subarray_sum([]) \ No newline at end of file diff --git a/tests/tests_1d.py b/tests/tests_1d.py new file mode 100644 index 00000000..aaa95e35 --- /dev/null +++ b/tests/tests_1d.py @@ -0,0 +1,28 @@ +""" +tests_1d.py + +Unit tests for two_sum in lab_1d.py. +""" + +import pytest +from labs.lab_1.lab_1d import two_sum + + +def test_basic_case(): + assert two_sum([2, 7, 11, 15], 9) == [0, 1] + + +def test_another_case(): + assert two_sum([3, 2, 4], 6) == [1, 2] + + +def test_with_negatives(): + assert two_sum([-1, -2, -3, -4, -5], -8) == [2, 4] + + +def test_same_number_used_twice(): + assert two_sum([3, 3], 6) == [0, 1] + + +def test_large_numbers(): + assert two_sum([1000000, 500000, 500000], 1000000) == [1, 2] \ No newline at end of file