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
57 changes: 30 additions & 27 deletions .github/workflows/ci-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,30 +51,33 @@ jobs:
run: "pylint solutions tests || echo '::warning title=Pylint Error(s)::Discuss solutions and trade-offs in code review.'"
shell: bash

py_tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: python version
run: python --version
shell: bash

- name: Check for test files
id: check_tests
run: |
test_files=$(find ./solutions/tests -type f -name "test_*.py")
if [ -n "$test_files" ]; then
echo "Found test files:"
echo "$test_files"
echo "has_tests=true" >> $GITHUB_OUTPUT
else
echo "No test files found matching pattern ./solutions/tests/test_*.py"
echo "has_tests=false" >> $GITHUB_OUTPUT
fi
shell: bash

- name: Python - Run Tests
if: steps.check_tests.outputs.has_tests == 'true'
run: python -m unittest
shell: bash
py_tests:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
run: python --version
shell: bash

- name: Check for test files
id: check_tests
run: |
test_files=$(find ./solutions/tests -type f -name "test_*.py")
if [ -n "$test_files" ]; then
echo "Found test files:"
echo "$test_files"
echo "has_tests=true" >> $GITHUB_ENV
else
echo "No test files found matching pattern ./solutions/tests/test_*.py"
echo "has_tests=false" >> $GITHUB_ENV
fi
shell: bash

- name: Python - Run Tests
if: env.has_tests == 'true'
env:
PYTHONPATH: ${{ github.workspace }}
run: python -m unittest discover -s solutions/tests
shell: bash
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,5 +122,8 @@
"source.fixAll.ruff": "explicit",
"source.organizeImports.ruff": "explicit"
}
}
},
"python.testing.unittestArgs": ["-v", "-s", "./solutions", "-p", "test_*.py"],
"python.testing.pytestEnabled": false,
"python.testing.unittestEnabled": true
}
33 changes: 33 additions & 0 deletions solutions/multiply.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
multiply.py

This module provides a function to multiply two numbers.
"""


def multiply(a: float, b: float) -> float:
"""
Multiplies two numbers and returns the result.

Args:
a (float): The first number.
b (float): The second number.

Returns:
float: The product of a and b.

Raises:
TypeError: If the inputs are not numbers.

Examples:
>>> multiply(2, 3)
6
>>> multiply(5.5, 2)
11.0
>>> multiply(-4, 3)
-12
"""
if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):
raise TypeError("Both inputs must be numbers.")

return a * b
39 changes: 39 additions & 0 deletions solutions/sum_positive_numbers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""
sum_positive_numbers.py

This module provides a function to sum only the positive numbers in a list.
"""

from typing import List


def sum_positive_numbers(numbers: List[float]) -> float:
"""
Calculate the sum of positive numbers in a given list.

Args:
numbers (List[float]): A list of floating point or integer numbers.

Returns:
float: The sum of all positive numbers in the list. If no positive numbers, returns 0.

Raises:
TypeError: If the input is not a list.
ValueError: If any element in the list is not a number.

Examples:
>>> sum_positive_numbers([1, -2, 3.5, 0, -1])
4.5
>>> sum_positive_numbers([-10, -20, -30])
0
>>> sum_positive_numbers([5, 10, 15])
30
"""
if not isinstance(numbers, list):
raise TypeError("Input must be a list.")

for num in numbers:
if not isinstance(num, (int, float)):
raise ValueError("All elements in the list must be numbers.")

return sum(num for num in numbers if num > 0)
37 changes: 37 additions & 0 deletions solutions/tests/test_multiply.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""
test_multiply.py

Unit tests for the multiply function.
"""

import unittest
from solutions.multiply import multiply


class TestMultiply(unittest.TestCase):
"""Tests for multiply function."""

def test_positive_numbers(self):
"""Should return the product of two positive numbers."""
self.assertEqual(multiply(2, 3), 6)

def test_negative_numbers(self):
"""Should return the correct product for negative numbers."""
self.assertEqual(multiply(-4, 3), -12)


def test_zero(self):
"""Should return 0 if either number is 0."""
self.assertEqual(multiply(3, 0), 0)

def test_floats(self):
"""Should correctly multiply floating point numbers."""
self.assertEqual(multiply(2.5, 2), 5.0)

def test_invalid_input_type(self):
"""Should raise TypeError if inputs are not numbers."""
with self.assertRaises(TypeError):
multiply("2", 3)

if __name__ == "__main__":
unittest.main()
42 changes: 42 additions & 0 deletions solutions/tests/test_sum_positive_numbers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""
test_sum_positive_numbers.py

Unit tests for the sum_positive_numbers function.
"""

import unittest
from solutions.sum_positive_numbers import sum_positive_numbers


class TestSumPositiveNumbers(unittest.TestCase):
"""Tests for sum_positive_numbers function."""

def test_positive_numbers(self):
"""Should return the sum of positive numbers."""
self.assertEqual(sum_positive_numbers([1, 2, 3]), 6)

def test_mixed_numbers(self):
"""Should sum only positive numbers and ignore negatives."""
self.assertEqual(sum_positive_numbers([1, -2, 3.5, 0, -1]), 4.5)

def test_all_negative_numbers(self):
"""Should return 0 if there are no positive numbers."""
self.assertEqual(sum_positive_numbers([-10, -20, -30]), 0)

def test_empty_list(self):
"""Should return 0 for an empty list."""
self.assertEqual(sum_positive_numbers([]), 0)

def test_invalid_input_type(self):
"""Should raise TypeError for non-list input."""
with self.assertRaises(TypeError):
sum_positive_numbers("invalid")

def test_non_numeric_elements(self):
"""Should raise ValueError if list contains non-numeric elements."""
with self.assertRaises(ValueError):
sum_positive_numbers([1, 2, "three"])


if __name__ == "__main__":
unittest.main()