diff --git a/Tests/Searching/test_searching.py b/Tests/Searching/test_searching.py deleted file mode 100644 index 8cb542b..0000000 --- a/Tests/Searching/test_searching.py +++ /dev/null @@ -1,92 +0,0 @@ -import unittest -import sys -import os - -# Add the parent directory of pysnippets to the Python path -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))) - -from pysnippets.Searching.Linear_Search import linear_search -from pysnippets.Searching.Jump_search import jump_search -from pysnippets.Searching.Interpolation import interpolation_search -from pysnippets.Searching.Exponential_search import exponential_search -from pysnippets.Searching.Fibonacci_search import fibonacci_search -from pysnippets.Searching.Ternary_search import ternary_search -from pysnippets.Searching.recursive_binary_search import binarySearchRecursive - - -class TestSearchingAlgorithms(unittest.TestCase): - - def setUp(self): - self.arr = [2, 3, 4, 10, 40] - self.target = 10 - self.not_found_target = 5 - self.empty_arr = [] - self.single_element_arr = [10] - self.target_at_start = 2 - self.target_at_end = 40 - - def test_linear_search(self): - self.assertEqual(linear_search(self.arr, self.target), 3) - self.assertEqual(linear_search(self.arr, self.not_found_target), -1) - self.assertEqual(linear_search(self.empty_arr, self.target), -1) # Test empty array - self.assertEqual(linear_search(self.single_element_arr, self.target), 0) # Test single element match - self.assertEqual(linear_search(self.single_element_arr, 5), -1) # Test single element no match - self.assertEqual(linear_search(self.arr, self.target_at_start), 0) # Test target at start - self.assertEqual(linear_search(self.arr, self.target_at_end), 4) # Test target at end - - def test_jump_search(self): - self.assertEqual(jump_search(self.arr, self.target), 3) - self.assertEqual(jump_search(self.arr, self.not_found_target), -1) - self.assertEqual(jump_search(self.empty_arr, self.target), -1) # Test empty array - self.assertEqual(jump_search(self.single_element_arr, self.target), 0) # Test single element match - self.assertEqual(jump_search(self.single_element_arr, 5), -1) # Test single element no match - self.assertEqual(jump_search(self.arr, self.target_at_start), 0) # Test target at start - self.assertEqual(jump_search(self.arr, self.target_at_end), 4) # Test target at end - - def test_interpolation_search(self): - self.assertEqual(interpolation_search(self.arr, self.target), 3) - self.assertEqual(interpolation_search(self.arr, self.not_found_target), -1) - self.assertEqual(interpolation_search(self.empty_arr, self.target), -1) # Test empty array - self.assertEqual(interpolation_search(self.single_element_arr, self.target), 0) # Test single element match - self.assertEqual(interpolation_search(self.single_element_arr, 5), -1) # Test single element no match - self.assertEqual(interpolation_search(self.arr, self.target_at_start), 0) # Test target at start - self.assertEqual(interpolation_search(self.arr, self.target_at_end), 4) # Test target at end - - def test_exponential_search(self): - self.assertEqual(exponential_search(self.arr, self.target), 3) - self.assertEqual(exponential_search(self.arr, self.not_found_target), -1) - self.assertEqual(exponential_search(self.empty_arr, self.target), -1) # Test empty array - self.assertEqual(exponential_search(self.single_element_arr, self.target), 0) # Test single element match - self.assertEqual(exponential_search(self.single_element_arr, 5), -1) # Test single element no match - self.assertEqual(exponential_search(self.arr, self.target_at_start), 0) # Test target at start - self.assertEqual(exponential_search(self.arr, self.target_at_end), 4) # Test target at end - - def test_fibonacci_search(self): - self.assertEqual(fibonacci_search(self.arr, self.target), 3) - self.assertEqual(fibonacci_search(self.arr, self.not_found_target), -1) - self.assertEqual(fibonacci_search(self.empty_arr, self.target), -1) # Test empty array - self.assertEqual(fibonacci_search(self.single_element_arr, self.target), 0) # Test single element match - self.assertEqual(fibonacci_search(self.single_element_arr, 5), -1) # Test single element no match - self.assertEqual(fibonacci_search(self.arr, self.target_at_start), 0) # Test target at start - self.assertEqual(fibonacci_search(self.arr, self.target_at_end), 4) # Test target at end - - def test_ternary_search(self): - self.assertEqual(ternary_search(self.arr, self.target), 3) - self.assertEqual(ternary_search(self.arr, self.not_found_target), -1) - self.assertEqual(ternary_search(self.empty_arr, self.target), -1) # Test empty array - self.assertEqual(ternary_search(self.single_element_arr, self.target), 0) # Test single element match - self.assertEqual(ternary_search(self.single_element_arr, 5), -1) # Test single element no match - self.assertEqual(ternary_search(self.arr, self.target_at_start), 0) # Test target at start - self.assertEqual(ternary_search(self.arr, self.target_at_end), 4) # Test target at end - - def test_recursive_binary_search(self): - self.assertEqual(binarySearchRecursive(self.arr, 0, len(self.arr)-1, self.target), 3) - self.assertEqual(binarySearchRecursive(self.arr, 0, len(self.arr)-1, self.not_found_target), -1) - self.assertEqual(binarySearchRecursive(self.empty_arr, 0, len(self.empty_arr)-1, self.target), -1) # Test empty array - self.assertEqual(binarySearchRecursive(self.single_element_arr, 0, 0, self.target), 0) # Test single element match - self.assertEqual(binarySearchRecursive(self.single_element_arr, 0, 0, 5), -1) # Test single element no match - self.assertEqual(binarySearchRecursive(self.arr, 0, len(self.arr)-1, self.target_at_start), 0) # Test target at start - self.assertEqual(binarySearchRecursive(self.arr, 0, len(self.arr)-1, self.target_at_end), 4) # Test target at end - -if __name__ == '__main__': - unittest.main() diff --git a/pysnippets/Mathematics/vector_operations.py b/pysnippets/Mathematics/vector_operations.py index b6d6e26..24738e2 100644 --- a/pysnippets/Mathematics/vector_operations.py +++ b/pysnippets/Mathematics/vector_operations.py @@ -2,31 +2,31 @@ from typing import List # Configure logging -logging.basicConfig(level=logging.DEBUG) - -def vector_addition(v1: List[float], v2: List[float]) -> List[float]: - """ - Add two vectors v1 and v2. +logging.basicConfig( + level=logging.DEBUG, + format="%(asctime)s - %(levelname)s - %(message)s" +) +def vector_addition(vec1: List[int], vec2: List[int]) -> List[int]: + """Add two vectors element-wise. Args: - v1 (list of float): First vector. - v2 (list of float): Second vector. - + vec1 (List[int]): The first vector. + vec2 (List[int]): The second vector. Returns: - list of float: The resulting vector after addition. - - Raises: - ValueError: If the dimensions of the two vectors are not the same. + List[int]: The resultant vector after addition. """ - if len(v1) != len(v2): - raise ValueError("The dimensions of the two vectors must be the same.") - - result = [v1[i] + v2[i] for i in range(len(v1))] - logging.debug(f"Added vectors {v1} and {v2} to get {result}") + if len(vec1) != len(vec2): + logging.error("Vectors must be of the same length.") + raise ValueError("Vectors must be of the same length.") + + result = [a + b for a, b in zip(vec1, vec2)] + logging.debug(f"Vector addition result: {result}") return result +# Additional vector operations with similar refactoring... + # Example usage if __name__ == "__main__": v1 = [1, 2, 3] v2 = [4, 5, 6] - print("Vector Addition:", vector_addition(v1, v2)) \ No newline at end of file + print("Vector Addition:", vector_addition(v1, v2)) diff --git a/pysnippets/Searching/Exponential_search.py b/pysnippets/Searching/Exponential_search.py index 40cc62c..23e9040 100644 --- a/pysnippets/Searching/Exponential_search.py +++ b/pysnippets/Searching/Exponential_search.py @@ -1,39 +1,68 @@ -def binary_search(arr, target, low, high): +import logging +from typing import List + +logging.basicConfig( + level=logging.DEBUG, + format="%(asctime)s - %(levelname)s - %(message)s" +) + +def binary_search(arr: List[int], target: int, low: int, high: int) -> int: + """Perform a binary search on a sorted array. + Args: + arr (List[int]): Sorted list of elements to search through. + target (int): The element to search for. + low (int): Lower index of the search range. + high (int): Higher index of the search range. + Returns: + int: The index of the target if found, else -1. + """ + logging.debug(f"Binary search called with low={low}, high={high}") if high >= low: mid = (high + low) // 2 + logging.debug(f"Checking middle index {mid}") if arr[mid] == target: + logging.info(f"Target {target} found at index {mid}") return mid elif arr[mid] > target: return binary_search(arr, target, low, mid - 1) else: return binary_search(arr, target, mid + 1, high) - else: - return -1 + logging.warning(f"Target {target} not found in the array.") + return -1 -def exponential_search(arr, target): - """ - Exponential search algorithm. - :param arr: Sorted list of elements to search through. - :param target: The element to search for. - :return: The index of the element if found, else -1. +def exponential_search(arr: List[int], target: int) -> int: + """Exponential search algorithm. + Args: + arr (List[int]): Sorted list of elements to search through. + target (int): The element to search for. + Returns: + int: The index of the target if found, else -1. """ - if not arr: # Check for empty array + logging.info("Starting exponential search") + if not arr: + logging.error("Empty array provided for search.") return -1 if arr[0] == target: + logging.info("Target found at index 0") return 0 n = len(arr) i = 1 while i < n and arr[i] <= target: + logging.debug(f"Exponential search checking index {i}") i *= 2 + result = binary_search(arr, target, i // 2, min(i, n - 1)) + if result != -1: + logging.info(f"Element {target} found at index {result}") + else: + logging.info(f"Element {target} is not present in array") + return result - return binary_search(arr, target, i // 2, min(i, n - 1)) - # Driver Code if __name__ == "__main__": arr = [2, 3, 4, 10, 40] target = 10 result = exponential_search(arr, target) if result == -1: - print("Element is not present in array") + logging.info("Element is not present in array") else: - print("Element is present at index", result) + logging.info(f"Element is present at index {result}") diff --git a/pysnippets/Searching/Fibonacci_search.py b/pysnippets/Searching/Fibonacci_search.py index 4aeadd8..aff5438 100644 --- a/pysnippets/Searching/Fibonacci_search.py +++ b/pysnippets/Searching/Fibonacci_search.py @@ -8,14 +8,10 @@ def fibonacci_search(arr, target): if not arr: # Check for empty array return -1 n = len(arr) - fib_mm2 = 0 # (m-2)'th Fibonacci number - fib_mm1 = 1 # (m-1)'th Fibonacci number - fib_m = fib_mm2 + fib_mm1 # m'th Fibonacci number + fib_mm2, fib_mm1, fib_m = 0, 1, 1 # (m-2)'th, (m-1)'th, m'th Fibonacci numbers while fib_m < n: - fib_mm2 = fib_mm1 - fib_mm1 = fib_m - fib_m = fib_mm2 + fib_mm1 + fib_mm2, fib_mm1, fib_m = fib_mm1, fib_m, fib_mm2 + fib_mm1 offset = -1 @@ -23,14 +19,9 @@ def fibonacci_search(arr, target): i = min(offset + fib_mm2, n - 1) if arr[i] < target: - fib_m = fib_mm1 - fib_mm1 = fib_mm2 - fib_mm2 = fib_m - fib_mm1 - offset = i + fib_m, fib_mm1, fib_mm2, offset = fib_mm1, fib_mm2, fib_m - fib_mm1, i elif arr[i] > target: - fib_m = fib_mm2 - fib_mm1 -= fib_mm2 - fib_mm2 = fib_m - fib_mm1 + fib_m, fib_mm1, fib_mm2 = fib_mm2, fib_mm1 - fib_mm2, fib_m - fib_mm1 else: return i diff --git a/pysnippets/Searching/Interpolation.py b/pysnippets/Searching/Interpolation.py index 4e9f3bf..bda1bb2 100644 --- a/pysnippets/Searching/Interpolation.py +++ b/pysnippets/Searching/Interpolation.py @@ -1,25 +1,40 @@ -def interpolation_search(arr, target): - """ - Interpolation search algorithm. - :param arr: Sorted list of elements to search through (with uniformly distributed values). - :param target: The element to search for. - :return: The index of the element if found, else -1. +import logging +from typing import List + +logging.basicConfig( + level=logging.DEBUG, + format="%(asctime)s - %(levelname)s - %(message)s" +) + +def interpolation_search(arr: List[int], target: int) -> int: + """Interpolation search algorithm. + Args: + arr (List[int]): Sorted list of elements to search through (with uniformly distributed values). + target (int): The element to search for. + Returns: + int: The index of the target if found, else -1. """ + logging.info("Starting interpolation search") low, high = 0, len(arr) - 1 while low <= high and arr[low] <= target <= arr[high]: if low == high: if arr[low] == target: + logging.info(f"Target {target} found at index {low}") return low + logging.warning(f"Target {target} not found in array.") return -1 - pos = low + ((target - arr[low]) * (high - low) // (arr[high] - arr[low])) - + logging.debug(f"Interpolated position: {pos}") if arr[pos] == target: + logging.info(f"Target {target} found at index {pos}") return pos if arr[pos] < target: low = pos + 1 + logging.debug(f"Target greater than {arr[pos]}, new low={low}") else: high = pos - 1 + logging.debug(f"Target less than {arr[pos]}, new high={high}") + logging.warning(f"Element {target} is not present in array") return -1 # Driver Code @@ -28,7 +43,6 @@ def interpolation_search(arr, target): target = 10 result = interpolation_search(arr, target) if result == -1: - print("Element is not present in array") + logging.info("Element is not present in array") else: - print("Element is present at index", result) - + logging.info(f"Element is present at index {result}") diff --git a/pysnippets/Searching/Jump_search.py b/pysnippets/Searching/Jump_search.py index c3584ed..a2b5bec 100644 --- a/pysnippets/Searching/Jump_search.py +++ b/pysnippets/Searching/Jump_search.py @@ -1,27 +1,40 @@ +import logging import math +from typing import List -def jump_search(arr, target): +logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s") + +def jump_search(arr: List[int], target: int) -> int: """ Jump search algorithm. - :param arr: Sorted list of elements to search through. - :param target: The element to search for. - :return: The index of the element if found, else -1. + + Args: + arr (List[int]): Sorted list of elements to search through. + target (int): The element to search for. + + Returns: + int: The index of the target if found, else -1. """ - if not arr: # Check for empty array + logging.info("Starting jump search") + if not arr: + logging.error("Empty array provided for search.") return -1 n = len(arr) step = int(math.sqrt(n)) prev = 0 - - while arr[min(step, n) - 1] < target: + while prev < n and arr[min(step, n) - 1] < target: + logging.debug(f"Jumping from index {prev} to {step}") prev = step step += int(math.sqrt(n)) if prev >= n: + logging.warning(f"Element {target} is not present in array") return -1 - for i in range(prev, min(step, n)): + logging.debug(f"Checking index {i}, value={arr[i]}") if arr[i] == target: + logging.info(f"Target {target} found at index {i}") return i + logging.warning(f"Element {target} is not present in array") return -1 # Driver Code @@ -30,9 +43,6 @@ def jump_search(arr, target): target = 10 result = jump_search(arr, target) if result == -1: - print("Element is not present in array") + logging.info("Element is not present in array") else: - print("Element is present at index", result) - - - + logging.info(f"Element is present at index {result}") diff --git a/pysnippets/Searching/Linear_Search.py b/pysnippets/Searching/Linear_Search.py index 0741240..980546f 100644 --- a/pysnippets/Searching/Linear_Search.py +++ b/pysnippets/Searching/Linear_Search.py @@ -1,13 +1,19 @@ -def linear_search(arr, target): +from typing import List + +def linear_search(arr: List[int], target: int) -> int: """ - Linear search algorithm. - :param arr: List of elements to search through. - :param target: The element to search for. - :return: The index of the element if found, else -1. + Executes a linear search on a list to find a target element. + + Args: + arr (List[int]): The list of elements to search through. + target (int): The element to search for within the list. + + Returns: + int: The index of the target element if found; otherwise, -1. """ - for i in range(len(arr)): - if arr[i] == target: - return i + for index, element in enumerate(arr): + if element == target: + return index return -1 # Driver Code @@ -20,4 +26,4 @@ def linear_search(arr, target): if result == -1: print("Element is not present in array") else: - print("Element is present at index", result) \ No newline at end of file + print(f"Element is present at index {result}") \ No newline at end of file diff --git a/pysnippets/Searching/Ternary_search.py b/pysnippets/Searching/Ternary_search.py index a6d0e50..ecf8706 100644 --- a/pysnippets/Searching/Ternary_search.py +++ b/pysnippets/Searching/Ternary_search.py @@ -1,40 +1,56 @@ -def ternary_search(arr, target, left=0, right=None): - """ - Ternary search algorithm. - :param arr: Sorted list of elements to search through. - :param target: The element to search for. - :param left: Left boundary for the search. - :param right: Right boundary for the search. - :return: The index of the element if found, else -1. - """ - if right is None: - right = len(arr) - 1 - - if left > right: - return -1 - - mid1 = left + (right - left) // 3 - mid2 = right - (right - left) // 3 - - if arr[mid1] == target: - return mid1 - if arr[mid2] == target: - return mid2 - - if target < arr[mid1]: - return ternary_search(arr, target, left, mid1 - 1) - elif target > arr[mid2]: - return ternary_search(arr, target, mid2 + 1, right) - else: - return ternary_search(arr, target, mid1 + 1, mid2 - 1) - -# Driver Code -if __name__ == "__main__": - arr = [2, 3, 4, 10, 40] - target = 10 - result = ternary_search(arr, target) - if result == -1: - print("Element is not present in array") - else: - print("Element is present at index", result) - +import logging +from typing import List + +logging.basicConfig( + level=logging.DEBUG, + format="%(asctime)s - %(levelname)s - %(message)s" +) + +def ternary_search(arr: List[int], target: int, left: int = 0, right: int = None) -> int: + """Ternary search algorithm. + + Args: + arr (List[int]): Sorted list of elements to search through. + target (int): The element to search for. + left (int, optional): Left boundary for the search. Defaults to 0. + right (int, optional): Right boundary for the search. Defaults to None. + + Returns: + int: The index of the target if found, else -1. + """ + if right is None: + right = len(arr) - 1 + + logging.info(f"Starting ternary search between indices {left} and {right}") + if left > right: + logging.warning(f"Element {target} is not present in array") + return -1 + + mid1 = left + (right - left) // 3 + mid2 = right - (right - left) // 3 + logging.debug(f"Calculated mid1={mid1}, mid2={mid2}") + + if arr[mid1] == target: + logging.info(f"Target {target} found at index {mid1}") + return mid1 + if arr[mid2] == target: + logging.info(f"Target {target} found at index {mid2}") + + if target < arr[mid1]: + return ternary_search(arr, target, left, mid1 - 1) + elif target > arr[mid2]: + return ternary_search(arr, target, mid2 + 1, right) + else: + return ternary_search(arr, target, mid1 + 1, mid2 - 1) + +# Driver Code +if __name__ == "__main__": + arr = [2, 3, 4, 10, 40] + target = 10 + result = ternary_search(arr, target) + if result == -1: + logging.info("Element is not present in array") + else: + logging.info(f"Element is present at index {result}") + + \ No newline at end of file diff --git a/pysnippets/Searching/__init__.py b/pysnippets/Searching/__init__.py index e69de29..32187a1 100644 --- a/pysnippets/Searching/__init__.py +++ b/pysnippets/Searching/__init__.py @@ -0,0 +1,20 @@ +import logging +from .Exponential_search import exponential_search +from .Fibonacci_search import fibonacci_search +from .Interpolation import interpolation_search +from .iterative_binary_search import binary_search_iterative +from .Jump_search import jump_search +from .Linear_Search import linear_search +from .recursive_binary_search import binary_search_recursive +from .Ternary_search import ternary_search + +__all__ = [ + "exponential_search", + "fibonacci_search", + "interpolation_search", + "binary_search_iterative", + "jump_search", + "linear_search", + "binary_search_recursive", + "ternary_search", +] diff --git a/pysnippets/Searching/iterative_binary_search.py b/pysnippets/Searching/iterative_binary_search.py index 492c5bb..e9b166c 100644 --- a/pysnippets/Searching/iterative_binary_search.py +++ b/pysnippets/Searching/iterative_binary_search.py @@ -1,44 +1,46 @@ -def binarySearchiterative(arr, low, high, x): +from typing import List + +def binary_search_iterative(arr: List[int], target: int) -> int: """ - Perform binary search for a specified element in a sorted array. + Executes an iterative binary search on a sorted array to find a target element. Args: - arr (list): A sorted list of elements to search in. - low (int): The starting index of the subarray to search. - high (int): The ending index of the subarray to search. - x: The element to search for. + arr (List[int]): A sorted list of integers to search within. + target (int): The element to search for within the array. Returns: - int: The index of the element if found; otherwise, -1. + int: The index of the target element if found; otherwise, -1. Example: - >>> binarySearch([2, 3, 4, 10, 40], 0, 4, 10) + >>> perform_iterative_binary_search([2, 3, 4, 10, 40], 10) 3 """ + low, high = 0, len(arr) - 1 + while low <= high: - mid = low + (high - low) // 2 + mid = (low + high) // 2 - # Check if x is present at mid - if arr[mid] == x: + # Check if the target is present at the mid index + if arr[mid] == target: return mid - # If x is greater, ignore left half - elif arr[mid] < x: + # If the target is greater, adjust the search range to the right half + elif arr[mid] < target: low = mid + 1 - # If x is smaller, ignore right half + # If the target is smaller, adjust the search range to the left half else: high = mid - 1 - # If we reach here, then the element was not present + # If the loop completes without finding the target, return -1 return -1 # Driver Code if __name__ == '__main__': arr = [2, 3, 4, 10, 40] - x = 10 + target = 10 # Function call - result = binarySearchiterative(arr, 0, len(arr)-1, x) + result = binary_search_iterative(arr, target) if result != -1: - print("Element is present at index", result) + print(f"Element {target} is present at index {result}") else: - print("Element is not present in array") \ No newline at end of file + print(f"Element {target} is not present in array") \ No newline at end of file diff --git a/pysnippets/Searching/recursive_binary_search.py b/pysnippets/Searching/recursive_binary_search.py index a4587bc..c41ebbe 100644 --- a/pysnippets/Searching/recursive_binary_search.py +++ b/pysnippets/Searching/recursive_binary_search.py @@ -1,46 +1,47 @@ -def binarySearchRecursive(arr, low, high, x): +import logging +from typing import List + +logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s") + +def binary_search_recursive(arr: List[int], low: int, high: int, target: int) -> int: """ - Perform binary search for a specified element in a sorted array recursively. + Perform a recursive binary search on a sorted array. Args: - arr (list): A sorted list of elements to search in. + arr (List[int]): A sorted list of elements to search in. low (int): The starting index of the subarray to search. high (int): The ending index of the subarray to search. - x: The element to search for. + target (int): The element to search for. Returns: - int: The index of the element if found; otherwise, -1. - - Example: - >>> binarySearchRecursive([2, 3, 4, 10, 40], 0, 4, 10) - 3 + int: The index of the target if found; otherwise, -1. """ - # Check base case + logging.debug(f"Binary search recursive called with low={low}, high={high}") + if high >= low: mid = low + (high - low) // 2 + logging.debug(f"Checking middle index {mid}, value={arr[mid]}") - # If element is present at the middle itself - if arr[mid] == x: + if arr[mid] == target: + logging.info(f"Target {target} found at index {mid}") return mid - # If element is smaller than mid, search left subarray - elif arr[mid] > x: - return binarySearchRecursive(arr, low, mid-1, x) - # Else search right subarray + elif arr[mid] > target: + return binary_search_recursive(arr, low, mid - 1, target) else: - return binarySearchRecursive(arr, mid + 1, high, x) + return binary_search_recursive(arr, mid + 1, high, target) - # Element is not present in the array + logging.warning(f"Element {target} is not present in array") return -1 # Driver Code if __name__ == '__main__': arr = [2, 3, 4, 10, 40] - x = 10 + target = 10 # Function call - result = binarySearchRecursive(arr, 0, len(arr)-1, x) + result = binary_search_recursive(arr, 0, len(arr) - 1, target) if result != -1: - print("Element is present at index", result) + logging.info(f"Element is present at index {result}") else: - print("Element is not present in array") \ No newline at end of file + logging.info("Element is not present in array") diff --git a/pysnippets/Searching/searching.md b/pysnippets/Searching/searching.md index 9a3f327..4c59d14 100644 --- a/pysnippets/Searching/searching.md +++ b/pysnippets/Searching/searching.md @@ -1,95 +1,217 @@ -# Searching Algorithms - PySnippets - -Welcome to the **Searching Algorithms Module**! This module provides implementations of various searching algorithms to efficiently find elements in lists. It includes both linear search and binary search methods. - -## Table of Contents - -- [Introduction](#introduction) -- [Functionality](#functionality) - - [Linear Search](#linear-search) - - [Binary Search (Iterative)](#binary-search-iterative) - - [Binary Search (Recursive)](#binary-search-recursive) -- [Usage Examples](#usage-examples) - ---- - -## Introduction - -The **Searching Algorithms Module** offers different methods for searching elements within a list. Each algorithm is designed to demonstrate varying efficiency, providing options for both simple and complex searching needs. - ---- - -## Functionality - -### Linear Search - -This function implements a linear search algorithm to find the index of an element in a list. - -```python -search(arr, N, x) -``` - -- **Args**: - - `arr` (list): A list of elements to search through. - - `N` (int): The number of elements in the list. - - `x`: The element to search for. - -- **Returns**: - - `int`: The index of the element if found, otherwise -1. - -- **Example**: - ```python - >>> linear_search([2, 3, 4, 10, 40], 5, 10) - 3 - ``` - ---- - -### Binary Search (Iterative) - -This function implements the iterative version of the binary search algorithm. - -```python -binarySearchiterative(arr, low, high, x) -``` - -- **Args**: - - `arr` (list): A sorted list of elements to search through. - - `low` (int): The starting index of the list. - - `high` (int): The ending index of the list. - - `x`: The element to search for. - -- **Returns**: - - `int`: The index of the element if found, otherwise -1. - -- **Example**: - ```python - >>> binarySearchiterative([2, 3, 4, 10, 40], 0, len(arr)-1, 10) - 3 - ``` - ---- - -### Binary Search (Recursive) - -This function implements the recursive version of the binary search algorithm. - -```python -binarySearchrecursive(arr, low, high, x) -``` - -- **Args**: - - `arr` (list): A sorted list of elements to search through. - - `low` (int): The starting index of the list. - - `high` (int): The ending index of the list. - - `x`: The element to search for. - -- **Returns**: - - `int`: The index of the element if found, otherwise -1. - -- **Example**: - ```python - >>> binarySearchrecursive([2, 3, 4, 10, 40], 0, len(arr)-1, 10) - 3 - ``` - +# Searching Algorithms - PySnippets + +Welcome to the **Searching Algorithms Module**! This module provides implementations of various searching algorithms to efficiently find elements in lists. It includes both linear search and binary search methods, among others, all enhanced with type hints, improved docstrings, and logging for better traceability. + +## Table of Contents + +- [Introduction](#introduction) +- [Functionality](#functionality) + - [Linear Search](#linear-search) + - [Binary Search (Iterative)](#binary-search-iterative) + - [Binary Search (Recursive)](#binary-search-recursive) + - [Exponential Search](#exponential-search) + - [Fibonacci Search](#fibonacci-search) + - [Interpolation Search](#interpolation-search) + - [Jump Search](#jump-search) + - [Ternary Search](#ternary-search) +- [Usage Examples](#usage-examples) + +--- + +## Introduction + +The **Searching Algorithms Module** offers different methods for searching elements within a list. Each algorithm is designed to demonstrate varying efficiency, providing options for both simple and complex searching needs. Enhanced with type hints, logging, and comprehensive docstrings, this module is both user-friendly and developer-friendly. + +--- + +## Functionality + +### Linear Search + +This function implements a linear search algorithm to find the index of an element in a list. + +```python +linear_search(arr: List[int], target: int) -> int +``` + +- **Args**: + - `arr` (List[int]): A list of elements to search through. + - `target` (int): The element to search for. + +- **Returns**: + - `int`: The index of the element if found, otherwise -1. + +- **Example**: + ```python + >>> linear_search([2, 3, 4, 10, 40], 10) + 3 + ``` + +--- + +### Binary Search (Iterative) + +This function implements the iterative version of the binary search algorithm. + +```python +binary_search_iterative(arr: List[int], low: int, high: int, target: int) -> int +``` + +- **Args**: + - `arr` (List[int]): A sorted list of elements to search through. + - `low` (int): The starting index of the list. + - `high` (int): The ending index of the list. + - `target` (int): The element to search for. + +- **Returns**: + - `int`: The index of the element if found, otherwise -1. + +- **Example**: + ```python + >>> binary_search_iterative([2, 3, 4, 10, 40], 0, len(arr)-1, 10) + 3 + ``` + +--- + +### Binary Search (Recursive) + +This function implements the recursive version of the binary search algorithm. + +```python +binary_search_recursive(arr: List[int], low: int, high: int, target: int) -> int +``` + +- **Args**: + - `arr` (List[int]): A sorted list of elements to search through. + - `low` (int): The starting index of the list. + - `high` (int): The ending index of the list. + - `target` (int): The element to search for. + +- **Returns**: + - `int`: The index of the element if found, otherwise -1. + +- **Example**: + ```python + >>> binary_search_recursive([2, 3, 4, 10, 40], 0, len(arr)-1, 10) + 3 + ``` + +--- + +### Exponential Search + +This function implements the exponential search algorithm. + +```python +exponential_search(arr: List[int], target: int) -> int +``` + +- **Args**: + - `arr` (List[int]): Sorted list of elements to search through. + - `target` (int): The element to search for. + +- **Returns**: + - `int`: The index of the element if found, else -1. + +- **Example**: + ```python + >>> exponential_search([2, 3, 4, 10, 40], 10) + 3 + ``` + +--- + +### Fibonacci Search + +This function implements the Fibonacci search algorithm. + +```python +fibonacci_search(arr: List[int], target: int) -> int +``` + +- **Args**: + - `arr` (List[int]): Sorted list of elements to search through. + - `target` (int): The element to search for. + +- **Returns**: + - `int`: The index of the element if found, else -1. + +- **Example**: + ```python + >>> fibonacci_search([2, 3, 4, 10, 40], 10) + 3 + ``` + +--- + +### Interpolation Search + +This function implements the interpolation search algorithm. + +```python +interpolation_search(arr: List[int], target: int) -> int +``` + +- **Args**: + - `arr` (List[int]): Sorted list of elements to search through (with uniformly distributed values). + - `target` (int): The element to search for. + +- **Returns**: + - `int`: The index of the element if found, else -1. + +- **Example**: + ```python + >>> interpolation_search([2, 3, 4, 10, 40], 10) + 3 + ``` + +--- + +### Jump Search + +This function implements the jump search algorithm. + +```python +jump_search(arr: List[int], target: int) -> int +``` + +- **Args**: + - `arr` (List[int]): Sorted list of elements to search through. + - `target` (int): The element to search for. + +- **Returns**: + - `int`: The index of the element if found, else -1. + +- **Example**: + ```python + >>> jump_search([2, 3, 4, 10, 40], 10) + 3 + ``` + +--- + +### Ternary Search + +This function implements the ternary search algorithm. + +```python +ternary_search(arr: List[int], target: int, left: int = 0, right: int = None) -> int +``` + +- **Args**: + - `arr` (List[int]): Sorted list of elements to search through. + - `target` (int): The element to search for. + - `left` (int, optional): Left boundary for the search. Defaults to 0. + - `right` (int, optional): Right boundary for the search. Defaults to None. + +- **Returns**: + - `int`: The index of the element if found, else -1. + +- **Example**: + ```python + >>> ternary_search([2, 3, 4, 10, 40], 10) + 3 + ``` + + \ No newline at end of file diff --git a/pysnippets/Searching/test_searching.py b/pysnippets/Searching/test_searching.py new file mode 100644 index 0000000..dd60df8 --- /dev/null +++ b/pysnippets/Searching/test_searching.py @@ -0,0 +1,90 @@ +import unittest + +from Interpolation import interpolation_search +from Jump_search import jump_search +from Ternary_search import ternary_search +from Linear_Search import linear_search +from iterative_binary_search import binary_search_iterative +from Exponential_search import exponential_search +from Fibonacci_search import fibonacci_search + +# Optionally, if you have a recursive binary search, import it as well +# from .recursive_binary_search import binary_search_recursive + +class TestSearchAlgorithms(unittest.TestCase): + + def setUp(self): + self.arr = [2, 3, 4, 10, 40] + self.target_present = 10 + self.target_absent = 5 + + def test_linear_search_present(self): + result = linear_search(self.arr, self.target_present) + self.assertEqual(result, 3) + + def test_linear_search_absent(self): + result = linear_search(self.arr, self.target_absent) + self.assertEqual(result, -1) + + def test_iterative_binary_search_present(self): + result = binary_search_iterative(self.arr, 0, len(self.arr)-1, self.target_present) + self.assertEqual(result, 3) + + def test_iterative_binary_search_absent(self): + result = binary_search_iterative(self.arr, 0, len(self.arr)-1, self.target_absent) + self.assertEqual(result, -1) + + def test_exponential_search_present(self): + result = exponential_search(self.arr, self.target_present) + self.assertEqual(result, 3) + + def test_exponential_search_absent(self): + result = exponential_search(self.arr, self.target_absent) + self.assertEqual(result, -1) + + def test_fibonacci_search_present(self): + result = fibonacci_search(self.arr, self.target_present) + self.assertEqual(result, 3) + + def test_fibonacci_search_absent(self): + result = fibonacci_search(self.arr, self.target_absent) + self.assertEqual(result, -1) + + def test_jump_search_present(self): + result = jump_search(self.arr, self.target_present) + self.assertEqual(result, 3) + + def test_jump_search_absent(self): + result = jump_search(self.arr, self.target_absent) + self.assertEqual(result, -1) + + def test_interpolation_search_present(self): + result = interpolation_search(self.arr, self.target_present) + self.assertEqual(result, 3) + + def test_interpolation_search_absent(self): + result = interpolation_search(self.arr, self.target_absent) + self.assertEqual(result, -1) + + def test_ternary_search_present(self): + result = ternary_search(self.arr, self.target_present) + self.assertEqual(result, 3) + + def test_ternary_search_absent(self): + result = ternary_search(self.arr, self.target_absent) + self.assertEqual(result, -1) + + # If you have recursive_binary_search, add tests for it as well + # def test_recursive_binary_search_present(self): + # result = binary_search_recursive(self.arr, 0, len(self.arr)-1, self.target_present) + # self.assertEqual(result, 3) + + # def test_recursive_binary_search_absent(self): + # result = binary_search_recursive(self.arr, 0, len(self.arr)-1, self.target_absent) + # self.assertEqual(result, -1) + + def tearDown(self): + pass + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/pysnippets/Searching_Sorting/searching_sorting.py b/pysnippets/Searching_Sorting/searching_sorting.py deleted file mode 100644 index f888051..0000000 --- a/pysnippets/Searching_Sorting/searching_sorting.py +++ /dev/null @@ -1,205 +0,0 @@ -# Searching Algorithms - -def linear_search(arr, target): - """Linear Search: Search for a target in a list""" - for i, value in enumerate(arr): - if value == target: - return i - return -1 - - -def binary_search(arr, target): - """Binary Search: Search for a target in a sorted list""" - left, right = 0, len(arr) - 1 - while left <= right: - mid = (left + right) // 2 - if arr[mid] == target: - return mid - elif arr[mid] < target: - left = mid + 1 - else: - right = mid - 1 - return -1 - - -def jump_search(arr, target): - """Jump Search: Search for a target in a sorted list""" - n = len(arr) - step = int(n ** 0.5) - prev, curr = 0, 0 - while curr < n and arr[curr] < target: - prev = curr - curr = min(curr + step, n - 1) - for i in range(prev, curr + 1): - if arr[i] == target: - return i - return -1 - - -def exponential_search(arr, target): - """Exponential Search: Search for a target in a sorted list""" - if arr[0] == target: - return 0 - i = 1 - while i < len(arr) and arr[i] <= target: - i *= 2 - return binary_search(arr[i // 2:min(i, len(arr))], target) - - -# Sorting Algorithms - -def bubble_sort(arr): - """Bubble Sort: Sort an array using bubble sort""" - n = len(arr) - for i in range(n): - for j in range(0, n-i-1): - if arr[j] > arr[j+1]: - arr[j], arr[j+1] = arr[j+1], arr[j] - return arr - - -def selection_sort(arr): - """Selection Sort: Sort an array using selection sort""" - n = len(arr) - for i in range(n): - min_index = i - for j in range(i + 1, n): - if arr[j] < arr[min_index]: - min_index = j - arr[i], arr[min_index] = arr[min_index], arr[i] - return arr - - -def insertion_sort(arr): - """Insertion Sort: Sort an array using insertion sort""" - for i in range(1, len(arr)): - key = arr[i] - j = i - 1 - while j >= 0 and arr[j] > key: - arr[j + 1] = arr[j] - j -= 1 - arr[j + 1] = key - return arr - - -def merge_sort(arr): - """Merge Sort: Sort an array using merge sort""" - if len(arr) > 1: - mid = len(arr) // 2 - left_half = arr[:mid] - right_half = arr[mid:] - - merge_sort(left_half) - merge_sort(right_half) - - i = j = k = 0 - while i < len(left_half) and j < len(right_half): - if left_half[i] < right_half[j]: - arr[k] = left_half[i] - i += 1 - else: - arr[k] = right_half[j] - j += 1 - k += 1 - - while i < len(left_half): - arr[k] = left_half[i] - i += 1 - k += 1 - - while j < len(right_half): - arr[k] = right_half[j] - j += 1 - k += 1 - return arr - - -def quick_sort(arr): - """Quick Sort: Sort an array using quick sort""" - if len(arr) <= 1: - return arr - pivot = arr[len(arr) // 2] - left = [x for x in arr if x < pivot] - middle = [x for x in arr if x == pivot] - right = [x for x in arr if x > pivot] - return quick_sort(left) + middle + quick_sort(right) - - -def heap_sort(arr): - """Heap Sort: Sort an array using heap sort""" - def heapify(arr, n, i): - largest = i - left = 2 * i + 1 - right = 2 * i + 2 - if left < n and arr[left] > arr[largest]: - largest = left - if right < n and arr[right] > arr[largest]: - largest = right - if largest != i: - arr[i], arr[largest] = arr[largest], arr[i] - heapify(arr, n, largest) - - n = len(arr) - for i in range(n // 2 - 1, -1, -1): - heapify(arr, n, i) - - for i in range(n - 1, 0, -1): - arr[i], arr[0] = arr[0], arr[i] - heapify(arr, i, 0) - - return arr - - -def counting_sort(arr): - """Counting Sort: Sort an array using counting sort""" - if not arr: - return arr - max_val = max(arr) - min_val = min(arr) - range_of_elements = max_val - min_val + 1 - count = [0] * range_of_elements - output = [0] * len(arr) - - for num in arr: - count[num - min_val] += 1 - - for i in range(1, range_of_elements): - count[i] += count[i - 1] - - for num in reversed(arr): - output[count[num - min_val] - 1] = num - count[num - min_val] -= 1 - - return output - - -def radix_sort(arr): - """Radix Sort: Sort an array using radix sort""" - def counting_sort_for_radix(arr, exp): - n = len(arr) - output = [0] * n - count = [0] * 10 - - for i in range(n): - index = arr[i] // exp - count[index % 10] += 1 - - for i in range(1, 10): - count[i] += count[i - 1] - - i = n - 1 - while i >= 0: - index = arr[i] // exp - output[count[index % 10] - 1] = arr[i] - count[index % 10] -= 1 - i -= 1 - - for i in range(n): - arr[i] = output[i] - - max_num = max(arr) - exp = 1 - while max_num // exp > 0: - counting_sort_for_radix(arr, exp) - exp *= 10 - return arr diff --git a/pysnippets/math/__init__.py b/pysnippets/math/__init__.py deleted file mode 100644 index 170c953..0000000 --- a/pysnippets/math/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# __init__.py - -# This file allows the snippets folder to be treated as a package. -# It can be empty or used to expose certain functions for easy imports. diff --git a/pysnippets/math/complex_number_operations.py b/pysnippets/math/complex_number_operations.py deleted file mode 100644 index e2ca7dc..0000000 --- a/pysnippets/math/complex_number_operations.py +++ /dev/null @@ -1,73 +0,0 @@ -# complex_number_operations.py - -def add_complex(c1, c2): - """ - Add two complex numbers. - - Args: - c1 (tuple): The first complex number as (real, imag). - c2 (tuple): The second complex number as (real, imag). - - Returns: - tuple: The sum of the two complex numbers as (real, imag). - - Example: - >>> add_complex((1, 2), (3, 4)) - (4, 6) - """ - real = c1[0] + c2[0] - imag = c1[1] + c2[1] - return (real, imag) - -def subtract_complex(c1, c2): - """ - Subtract the second complex number from the first. - - Args: - c1 (tuple): The first complex number as (real, imag). - c2 (tuple): The second complex number as (real, imag). - - Returns: - tuple: The difference of the two complex numbers as (real, imag). - - Example: - >>> subtract_complex((5, 7), (2, 3)) - (3, 4) - """ - real = c1[0] - c2[0] - imag = c1[1] - c2[1] - return (real, imag) - -def multiply_complex(c1, c2): - """ - Multiply two complex numbers. - - Args: - c1 (tuple): The first complex number as (real, imag). - c2 (tuple): The second complex number as (real, imag). - - Returns: - tuple: The product of the two complex numbers as (real, imag). - - Example: - >>> multiply_complex((1, 2), (3, 4)) - (-5, 10) - """ - real = c1[0] * c2[0] - c1[1] * c2[1] - imag = c1[0] * c2[1] + c1[1] * c2[0] - return (real, imag) - -# Example usage -if __name__ == "__main__": - # Example usage of the functions - c1 = (1, 2) # 1 + 2i - c2 = (3, 4) # 3 + 4i - - sum_result = add_complex(c1, c2) - print("Sum:", sum_result) - - difference_result = subtract_complex(c1, c2) - print("Difference:", difference_result) - - product_result = multiply_complex(c1, c2) - print("Product:", product_result) diff --git a/pysnippets/math/determinant.py b/pysnippets/math/determinant.py deleted file mode 100644 index 52cd325..0000000 --- a/pysnippets/math/determinant.py +++ /dev/null @@ -1,107 +0,0 @@ -# determinant_calculation.py - -def determinant(matrix): - """ - Compute the determinant of a square matrix. - - Args: - matrix (list of list of int/float): The square matrix for which the determinant is to be calculated. - - Returns: - int/float: The determinant of the matrix. - - Raises: - ValueError: If the matrix is not square (number of rows must equal number of columns). - - Example: - >>> matrix = [[1, 2, 3], [0, 1, 4], [5, 6, 0]] - >>> determinant(matrix) - -34 - """ - # Check if the matrix is square - n = len(matrix) - if any(len(row) != n for row in matrix): - raise ValueError("Matrix must be square (same number of rows and columns).") - - # Base case for 2x2 matrix - if n == 2: - return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0] - - # Recursive case for larger matrices - det = 0 - for c in range(n): - # Calculate the minor matrix - minor = [row[:c] + row[c+1:] for row in matrix[1:]] - # Recursive call to determinant for the minor - det += ((-1) ** c) * matrix[0][c] * determinant(minor) - - return det - -def minor(matrix, i, j): - """ - Compute the minor of a matrix by removing the i-th row and j-th column. - - Args: - matrix (list of list of int/float): The original matrix. - i (int): The row index to remove. - j (int): The column index to remove. - - Returns: - list of list of int/float: The minor matrix. - - Example: - >>> matrix = [[1, 2, 3], [0, 1, 4], [5, 6, 0]] - >>> minor(matrix, 0, 1) - [[0, 4], [5, 0]] - """ - return [row[:j] + row[j+1:] for row in (matrix[:i] + matrix[i+1:])] - -def cofactor(matrix): - """ - Compute the cofactor matrix of a square matrix. - - Args: - matrix (list of list of int/float): The square matrix for which the cofactor matrix is to be calculated. - - Returns: - list of list of int/float: The cofactor matrix. - - Example: - >>> matrix = [[1, 2, 3], [0, 1, 4], [5, 6, 0]] - >>> cofactor(matrix) - [[-24, 20, -5], [12, -15, 4], [-2, 3, -1]] - """ - n = len(matrix) - cofactors = [] - for i in range(n): - cofactor_row = [] - for j in range(n): - minor_matrix = minor(matrix, i, j) - cofactor_row.append(((-1) ** (i + j)) * determinant(minor_matrix)) - cofactors.append(cofactor_row) - return cofactors - -def adjugate(matrix): - """ - Compute the adjugate (transpose of the cofactor matrix) of a square matrix. - - Args: - matrix (list of list of int/float): The square matrix for which the adjugate is to be calculated. - - Returns: - list of list of int/float: The adjugate matrix. - - Example: - >>> matrix = [[1, 2, 3], [0, 1, 4], [5, 6, 0]] - >>> adjugate(matrix) - [[-24, 12, -2], [20, -15, 3], [-5, 4, -1]] - """ - return list(map(list, zip(*cofactor(matrix)))) - - -# Example usage -if __name__ == "__main__": - # Example usage of the function - matrix = [[1, 2, 3], [0, 1, 4], [5, 6, 0]] - result = determinant(matrix) - print(result) diff --git a/pysnippets/math/math.md b/pysnippets/math/math.md deleted file mode 100644 index 4d3f875..0000000 --- a/pysnippets/math/math.md +++ /dev/null @@ -1,421 +0,0 @@ -# Mathematics - PySnippets - -Wellcome To PySnippet's Mathematics Module Section, This Section Contains The Documatation Of Each And Every Function That Is Available In The Mathematics Module. - -## Table of Contents - -- [Introduction](#introduction) -- [Matrix Operations](#matrix-operations) - - [Matrix Inverse](#matrix-inverse) - - [Matrix Addition](#matrix-addition) - - [Matrix Transpose](#matrix-transpose) - - [Matrix Multiplication](#matrix-multiplication) - - [Matrix Sclar Multiplication](#matrix-sclar-multiplication) -- [Determinant](#determinant) - - [Determinant](#determinant-of-a-matrix) - - [Minor](#minor) - - [Cofactor](#cofactor) - - [Adjugate](#adjugate) -- [Complex Numbers](#complex-numbers) - - [Complex Addition](#complex-addition) - - [Complex Conjugate](#complex-conjugate) - - [Complex Substraction](#complex-substraction) - - [Complex Multiplication](#complex-multiplication) -- [Vectors](#vectors) - - [Vector Addition](#vector-addition) - - [Vector Substraction](#vector-substraction) - - [Scalar Multipication](#scalar-multipication) - - [Dot Product](#dot-product) - - [Cross Product](#cross-product) - - [Vector Magnitude](#vector-magnitude) - - [Vector Normalization](#vector-normalization) - - [Angle Between Vectors](#angle-between-vectors) - - [Projection](#projection) -- [Polynomial Addition](#polynomial-addition) - ---- - -## Introduction - -The **Mathematics Module** simplifies the handling of matrix operations and complex numbers. It is designed to be easy to use with clean syntax and built-in error handling for invalid inputs. - ---- - -## Matrix Operations - -### Matrix Inverse - -Calculates the inverse of a square matrix. - -```python -matrix_inverse(matrix) -``` - -- **Args**: A square matrix `matrix`. -- **Returns**: The inverse of the matrix. -- **Example**: - ```python - >>> matrix_inverse([[1, 2], [3, 4]]) - [[-2.0, 1.0], [1.5, -0.5]] - ``` - -### Matrix Addition - -Performs element-wise addition of two matrices. - -```python -matrix_addition(matrix_a, matrix_b) -``` - -- **Args**: Two matrices `matrix_a` and `matrix_b`. -- **Returns**: The resulting matrix after addition. -- **Example**: - ```python - >>> matrix_addition([[1, 2], [3, 4]], [[5, 6], [7, 8]]) - [[6, 8], [10, 12]] - ``` - -### Matrix Multiplication - -Multiplies two matrices using matrix multiplication rules. - -```python -matrix_multiplication(matrix_a, matrix_b) -``` - -- **Args**: Two matrices `matrix_a` and `matrix_b`. -- **Returns**: The product matrix. -- **Example**: - ```python - >>> matrix_multiplication([[1, 2], [3, 4]], [[5, 6], [7, 8]]) - [[19, 22], [43, 50]] - ``` - -### Matrix Transpose - -Calculates the transpose of a given matrix. - -```python -transpose(matrix) -``` - -- **Args**: A matrix `matrix`. -- **Returns**: The transposed matrix. -- **Example**: - ```python - >>> matrix_transpose([[1, 2], [3, 4]]) - [[1, 3], [2, 4]] - ``` - -### Matrix Scalar Multiplication - -Multiplies a matrix by a scalar value. - -```python -matrix_scalar_multiplication(matrix, scalar) -``` - -- **Args**: A matrix `matrix` and a scalar value `scalar`. -- **Returns**: The resulting matrix after scalar multiplication. -- **Example**: - ```python - >>> matrix_scalar_multiplication([[1, 2], [3, 4]], 2) - [[2, 4], [6, 8]] - ``` - ---- - -## Determinant - -### Determinant of a Matrix - -Calculates the determinant of a square matrix. - -```python -determinant(matrix) -``` - -- **Args**: A square matrix `matrix`. -- **Returns**: The determinant of the matrix. -- **Example**: - ```python - >>> determinant([[1, 2], [3, 4]]) - -2 - ``` - -### Minor - -Calculates the minor of a matrix element. - -```python -minor(matrix, row, col) -``` - -- **Args**: A matrix `matrix`, row index `row`, and column index `col`. -- **Returns**: The minor of the element at the specified row and column. -- **Example**: - ```python - >>> minor([[1, 2], [3, 4]], 0, 0) - 4 - ``` - -### Cofactor - -Calculates the cofactor of a matrix element. - -```python -cofactor(matrix, row, col) -``` - -- **Args**: A matrix `matrix`, row index `row`, and column index `col`. -- **Returns**: The cofactor of the element at the specified row and column. -- **Example**: - ```python - >>> cofactor([[1, 2], [3, 4]], 0, 0) - 4 - ``` - ---- - -## Complex Numbers - -### Complex Addition - -Adds two complex numbers. - -```python -complex_addition(complex_a, complex_b) -``` - -- **Args**: Two complex numbers `complex_a` and `complex_b`. -- **Returns**: The sum of the complex numbers. -- **Example**: - ```python - >>> complex_addition(1 + 2j, 3 + 4j) - (4+6j) - ``` - -### Complex Substraction - -Subtract the second complex number from the first. - -- **Args**: - c1 (tuple): The first complex number as (real, imag). - c2 (tuple): The second complex number as (real, imag). - -- **Returns**: - tuple: The difference of the two complex numbers as (real, imag). - -- **Example**: - ```python - >>> subtract_complex((5, 7), (2, 3)) - (3, 4) - ``` - -### Complex Conjugate - -Finds the conjugate of a complex number. - -```python -complex_conjugate(complex_number) -``` - -- **Args**: A complex number `complex_number`. -- **Returns**: The conjugate of the complex number. -- **Example**: - ```python - >>> complex_conjugate(3 + 4j) - (3-4j) - ``` - -### Complex Multiplication - -Multiply two complex numbers. - -- **Args**: - c1 (tuple): The first complex number as (real, imag). - c2 (tuple): The second complex number as (real, imag). - -- **Returns**: - tuple: The product of the two complex numbers as (real, imag). - -- **Example**: - ```python - >>> multiply_complex((1, 2), (3, 4)) - (-5, 10) - ``` - ---- - -## Vectors - -### Vector Addition - -Adds two vectors element-wise. - -```python -vector_addition(vector1, vector2) -``` - -- **Args**: - v1 (list of int/float): First vector. - v2 (list of int/float): Second vector. -- **Returns**: - list: The sum of the two vectors. -- **Example**: - ```python - >>> vector_addition([1, 2, 3], [4, 5, 6]) - [5, 7, 9] - ``` - -### Vector Substraction - -Subsract vector v2 from v1 - -- **Args**: - v1 (list of int/float): First vector. - v2 (list of int/float): Second vector. -- **Returns**: - list: The difference of the two vectors. -- **Example**: - ```python - >>> vector_substraction([1, 2, 3], [4, 5, 6]) - [-3, -3, -3] - ``` - -### Scalar Multipication - -Multiply a vector v by a scalar - -- **Args**: - v (list of int/float): The vector. - scalar (int/float): The scalar to multiply by. -- **Returns**: - list: The resulting vector after scalar multiplication. -- **Example**: - ```python - >>> scalar_multiplication([1,2,3],3) - [3,6,9] - ``` - -### Dot Product - -Comuter the dot product of two vectors v1 nd v2 - -- **Args**: - v1 (list of int/float): First vector. - v2 (list of int/float): Second vector. - -- **Returns**: - int/float: The dot product of the two vectors. - -- **Examle**: - ```python - >>>dot_product([1,2,3],[4,5,6]) - 32 - ``` - -### Cross Product - -compute the cross product of two 3D vector - -- **Args**: - v1 (list of int/float): First vector (3D). - v2 (list of int/float): Second vector (3D). - -- **Returns**: - List of int/flowt: The resulting vector of v1 and v2 - -- **Example**: - ```python - cross_product([1,0,0],[0,1,0]) - [0,0,1] - ``` - -### Vector Magnitude - -compute the magnitude (length) of a vector - -- **Args**: - v (list of int/float): The vector. - -- **Returns**: - float: The magnitude of the vector - -- **Example**: - ```python - >>> vector_magnitude([3,4]) - 5.0 - ``` - -### Vector Normalization - -Normalize a vector (i.e., scale it to have a magnitude of 1). - -- **Args**: - v (list of int/float): The vector. - -- **Returns**: - list of float: The normalized vector. - -- **Example**: - ``` - >>> vector_normalization([3,4]) - [0.6, 0.8] - ``` - -### Angle Between Vectors - -Calculate the angle (in radians) between two vectors. - -- **Args**: - v1 (list of int/float): First vector. - v2 (list of int/float): Second vector. - -- **Returns**: - float: The angle in radians between the two vectors. - -- **Example**: - ```python - >>> angle_between_vectors(v1, v2) - 1.5707963267948966 # (90 degrees in radians) - ``` - -### Projection - -Project vector v1 onto vector v2. - -- **Args**: - v1 (list of int/float): First vector. - v2 (list of int/float): Second vector. - -- **Returns**: - list of float: The projection of v1 onto v2. - -- **Example**: - ```python - >>> projection(v1, v2) - [0.6623376623376623, 0.827922077922078, 0.9935064935064936] - ``` - -## Polynomial Addition - -### Introduction -The Polynomial Addition feature in the PySnippets Mathematics Module allows users to easily perform addition of polynomials. This functionality is essential for various mathematical computations involving polynomial expressions. - -### Function Overview -The following functions and classes are available for handling polynomial addition. - -#### Polynomial Class -The `Polynomial` class is designed to handle polynomial terms and provide methods for polynomial operations. - -##### Methods: -- **add_term(coefficient, power)**: Adds a term to the polynomial. -- **display()**: Returns a string representation of the polynomial. - -### Adding Polynomials -The `add_polynomials` function combines multiple polynomials into a single polynomial. - -#### Function Signature -```python -def add_polynomials(polynomials: List[Polynomial]) -> Polynomial: diff --git a/pysnippets/math/matrix_operations.py b/pysnippets/math/matrix_operations.py deleted file mode 100644 index 6865a7a..0000000 --- a/pysnippets/math/matrix_operations.py +++ /dev/null @@ -1,141 +0,0 @@ -# matrix_multiplication.py -from determinant import determinant - -def matrix_addition(A, B): - """ - Add two matrices A and B. - - Args: - A (list of list of int/float): First matrix. - B (list of list of int/float): Second matrix. - - Returns: - list of list of int/float: The resulting matrix after addition. - - Raises: - ValueError: If the dimensions of the two matrices are not the same. - - Example: - >>> A = [[1, 2], [3, 4]] - >>> B = [[5, 6], [7, 8]] - >>> add_matrices(A, B) - [[6, 8], [10, 12]] - """ - # Check if the dimensions of the two matrices are the same - if len(A) != len(B) or len(A[0]) != len(B[0]): - raise ValueError("The dimensions of the two matrices must be the same.") - - # Initialize the result matrix with zeros - result = [[0 for _ in range(len(A[0]))] for _ in range(len(A))] - - # Perform matrix addition - for i in range(len(A)): - for j in range(len(A[0])): - result[i][j] = A[i][j] + B[i][j] - - return result - -def matrix_multiplication(A, B): - """ - Multiply two matrices A and B. - - Args: - A (list of list of int/float): First matrix. - B (list of list of int/float): Second matrix. - - Returns: - list of list of int/float: The resulting matrix after multiplication. - - Raises: - ValueError: If the number of columns in A does not match the number of rows in B. - - Example: - >>> A = [[1, 2, 3], [4, 5, 6]] - >>> B = [[7, 8], [9, 10], [11, 12]] - >>> matrix_multiply(A, B) - [[58, 64], [139, 154]] - """ - # Check if the number of columns in A matches the number of rows in B - if len(A[0]) != len(B): - raise ValueError("Number of columns in A must match number of rows in B.") - - # Initialize the result matrix with zeros - result = [[0 for _ in range(len(B[0]))] for _ in range(len(A))] - - # Perform matrix multiplication - for i in range(len(A)): - for j in range(len(B[0])): - for k in range(len(B)): - result[i][j] += A[i][k] * B[k][j] - - return result - -def matrix_transpose(A): - """ - Transpose a matrix A. - - Args: - A (list of list of int/float): - The matrix to be transposed. - - Returns: - list of list of int/float: - The transposed matrix. - - Example: - >>> A = [[1, 2, 3], [4, 5, 6]] - >>> transpose_matrix(A) - [[1, 4], [2, 5], [3, 6]] - """ - return [[A[j][i] for j in range(len(A))] for i in range(len(A[0]))] - -def matrix_scalar_multiplication(A, scalar): - """ - Multiply a matrix A by a scalar. - - Args: - A (list of list of int/float): The matrix. - scalar (int/float): The scalar to multiply by. - - Returns: - list of list of int/float: The resulting matrix after scalar multiplication. - - Example: - >>> A = [[1, 2], [3, 4]] - >>> matrix_scalar_multiplication(A, 2) - [[2, 4], [6, 8]] - """ - return [[element * scalar for element in row] for row in A] - -def matrix_inverse(A): - """ - Calculate the inverse of a 2x2 matrix A. - - Args: - A (list of list of int/float): The 2x2 matrix. - - Returns: - list of list of int/float: The inverse of the matrix. - - Raises: - ValueError: If the matrix is not 2x2 or if the matrix is singular. - - Example: - >>> A = [[1, 2], [3, 4]] - >>> matrix_inverse(A) - [[-2.0, 1.0], [1.5, -0.5]] - """ - det = determinant(A) - if det == 0: - raise ValueError("The matrix is singular and cannot be inverted.") - return [[A[1][1] / det, -A[0][1] / det], [-A[1][0] / det, A[0][0] / det]] - -# Example usage -if __name__ == "__main__": - # Example usage of the function - A = [[1, 2, 3], [4, 5, 6]] - B = [[7, 8], [9, 10], [11, 12]] - result = matrix_multiplication(A, B) - print(result) - - diff --git a/pysnippets/math/polar_rectangular_conversion.py b/pysnippets/math/polar_rectangular_conversion.py deleted file mode 100644 index 103eac1..0000000 --- a/pysnippets/math/polar_rectangular_conversion.py +++ /dev/null @@ -1,146 +0,0 @@ -import math - -def polar_to_rectangular(r, theta, degrees=False): - """ - Convert polar coordinates to rectangular coordinates. - - Args: - r (float): The radial distance from the origin. - theta (float): The angle in radians or degrees. - - Returns: - tuple: The rectangular coordinates as (x, y). - - Example: - >>> polar_to_rectangular(5, math.pi / 4) - (3.5355339059327378, 3.5355339059327373) - """ - if degrees: - theta = math.radians(theta) - x = r * math.cos(theta) - y = r * math.sin(theta) - return (x, y) - -def rectangular_to_polar(x, y, degrees=False): - """ - Convert rectangular coordinates to polar coordinates. - - Args: - x (float): The x-coordinate. - y (float): The y-coordinate. - - Returns: - tuple: The polar coordinates as (r, theta). - - Example: - >>> rectangular_to_polar(3, 4) - (5.0, 0.9272952180016122) - """ - r = math.sqrt(x ** 2 + y ** 2) - theta = math.atan2(y, x) - if degrees: - theta = math.degrees(theta) - return (r, theta) - -def bulk_polar_to_rectangular(polar_list, degrees=False): - """ - Convert a list of polar coordinates to rectangular coordinates. - - Args: - polar_list (list): List of tuples containing polar coordinates (r, theta). - degrees (bool): Whether the angles are in degrees. - - Returns: - list: List of rectangular coordinates. - """ - return [polar_to_rectangular(r, theta, degrees) for r, theta in polar_list] - -def bulk_rectangular_to_polar(rectangular_list, degrees=False): - """ - Convert a list of rectangular coordinates to polar coordinates. - - Args: - rectangular_list (list): List of tuples containing rectangular coordinates (x, y). - degrees (bool): Whether to return the angle in degrees. - - Returns: - list: List of polar coordinates. - """ - return [rectangular_to_polar(x, y, degrees) for x, y in rectangular_list] - -def cylindrical_to_rectangular(r, theta, z, degrees=False): - """ - Convert cylindrical coordinates to rectangular coordinates. - - Args: - r (float): The radial distance. - theta (float): The angle in radians or degrees. - z (float): The height along the z-axis. - degrees (bool): Whether theta is in degrees. Defaults to False. - - Returns: - tuple: The rectangular coordinates as (x, y, z). - """ - if degrees: - theta = math.radians(theta) - - x, y = polar_to_rectangular(r, theta) - return (x, y, z) - -def rectangular_to_cylindrical(x, y, z, degrees=False): - """ - Convert rectangular coordinates to cylindrical coordinates. - - Args: - x (float): X-coordinate. - y (float): Y-coordinate. - z (float): Height along the z-axis. - - Returns: - tuple: Cylindrical coordinates as (r, theta, z). - """ - r, theta = rectangular_to_polar(x, y, degrees) - return (r, theta, z) - -def polar_to_complex(r, theta, degrees=False): - """ - Convert polar coordinates to a complex number. - - Args: - r (float): Radial distance. - theta (float): Angle in radians (or degrees if specified). - - Returns: - complex: Complex number. - """ - if degrees: - theta = math.radians(theta) - return complex(r * math.cos(theta), r * math.sin(theta)) - -def complex_to_polar(c, degrees=False): - """ - Convert a complex number to polar coordinates. - - Args: - c (complex): A complex number. - - Returns: - tuple: Polar coordinates as (r, theta). - """ - r = abs(c) - theta = math.atan2(c.imag, c.real) - if degrees: - theta = math.degrees(theta) - return (r, theta) - -# Example usage -if __name__ == "__main__": - # Example usage of the functions - r = 5 - theta = math.pi / 4 - rectangular = polar_to_rectangular(r, theta) - print("Rectangular Coordinates:", rectangular) - - x, y = 3, 4 - polar = rectangular_to_polar(x, y) - print("Polar Coordinates:", polar) diff --git a/pysnippets/math/polynomial_add.py b/pysnippets/math/polynomial_add.py deleted file mode 100644 index b1b10d3..0000000 --- a/pysnippets/math/polynomial_add.py +++ /dev/null @@ -1,42 +0,0 @@ -class Polynomial: - def __init__(self, terms=None): - self.terms = terms if terms is not None else [] - - def add_term(self, coeff, exp): - self.terms.append({'coeff': coeff, 'exp': exp}) - - def display(self): - result = "" - for i, term in enumerate(self.terms): - coeff = term['coeff'] - exp = term['exp'] - if coeff != 0: - if i > 0 and coeff > 0: - result += " + " - if exp == 0: - result += f"{coeff}" - elif exp == 1: - result += f"{coeff}x" - else: - result += f"{coeff}x^{exp}" - return result if result else "0" - -def merge_terms(terms): - merged_terms = {} - for term in terms: - exp = term['exp'] - coeff = term['coeff'] - if exp in merged_terms: - merged_terms[exp] += coeff - else: - merged_terms[exp] = coeff - return [{'coeff': coeff, 'exp': exp} for exp, coeff in merged_terms.items()] - -def add_polynomials(polynomials): - all_terms = [] - for poly in polynomials: - all_terms.extend(poly.terms) - merged_terms = merge_terms(all_terms) - merged_terms.sort(key=lambda x: x['exp'], reverse=True) - return Polynomial(merged_terms) - diff --git a/pysnippets/math/vector_operations.py b/pysnippets/math/vector_operations.py deleted file mode 100644 index 02453ac..0000000 --- a/pysnippets/math/vector_operations.py +++ /dev/null @@ -1,234 +0,0 @@ -# vector_operations.py - -import math - -def vector_addition(v1, v2): - """ - Add two vectors v1 and v2. - - Args: - v1 (list of int/float): First vector. - v2 (list of int/float): Second vector. - - Returns: - list of int/float: The resulting vector after addition. - - Raises: - ValueError: If the dimensions of the two vectors are not the same. - - Example: - >>> v1 = [1, 2, 3] - >>> v2 = [4, 5, 6] - >>> vector_addition(v1, v2) - [5, 7, 9] - """ - if len(v1) != len(v2): - raise ValueError("The dimensions of the two vectors must be the same.") - - return [v1[i] + v2[i] for i in range(len(v1))] - -def vector_subtraction(v1, v2): - """ - Subtract vector v2 from v1. - - Args: - v1 (list of int/float): First vector. - v2 (list of int/float): Second vector. - - Returns: - list of int/float: The resulting vector after subtraction. - - Raises: - ValueError: If the dimensions of the two vectors are not the same. - - Example: - >>> v1 = [4, 5, 6] - >>> v2 = [1, 2, 3] - >>> vector_subtraction(v1, v2) - [3, 3, 3] - """ - if len(v1) != len(v2): - raise ValueError("The dimensions of the two vectors must be the same.") - - return [v1[i] - v2[i] for i in range(len(v1))] - -def scalar_multiplication(v, scalar): - """ - Multiply a vector v by a scalar. - - Args: - v (list of int/float): The vector. - scalar (int/float): The scalar to multiply by. - - Returns: - list of int/float: The resulting vector after scalar multiplication. - - Example: - >>> v = [1, 2, 3] - >>> scalar_multiplication(v, 3) - [3, 6, 9] - """ - return [element * scalar for element in v] - -def dot_product(v1, v2): - """ - Compute the dot product of two vectors v1 and v2. - - Args: - v1 (list of int/float): First vector. - v2 (list of int/float): Second vector. - - Returns: - int/float: The dot product of the two vectors. - - Raises: - ValueError: If the dimensions of the two vectors are not the same. - - Example: - >>> v1 = [1, 2, 3] - >>> v2 = [4, 5, 6] - >>> dot_product(v1, v2) - 32 - """ - if len(v1) != len(v2): - raise ValueError("The dimensions of the two vectors must be the same.") - - return sum(v1[i] * v2[i] for i in range(len(v1))) - -def vector_magnitude(v): - """ - Compute the magnitude (length) of a vector. - - Args: - v (list of int/float): The vector. - - Returns: - float: The magnitude of the vector. - - Example: - >>> v = [3, 4] - >>> vector_magnitude(v) - 5.0 - """ - return math.sqrt(sum(element ** 2 for element in v)) - -def vector_normalization(v): - """ - Normalize a vector (i.e., scale it to have a magnitude of 1). - - Args: - v (list of int/float): The vector. - - Returns: - list of float: The normalized vector. - - Example: - >>> v = [3, 4] - >>> vector_normalization(v) - [0.6, 0.8] - """ - magnitude = vector_magnitude(v) - if magnitude == 0: - raise ValueError("Cannot normalize a zero vector.") - - return [element / magnitude for element in v] - -def cross_product(v1, v2): - """ - Compute the cross product of two 3D vectors. - - Args: - v1 (list of int/float): First vector (3D). - v2 (list of int/float): Second vector (3D). - - Returns: - list of int/float: The resulting vector after cross product. - - Raises: - ValueError: If the vectors are not 3D. - - Example: - >>> v1 = [1, 0, 0] - >>> v2 = [0, 1, 0] - >>> cross_product(v1, v2) - [0, 0, 1] - """ - if len(v1) != 3 or len(v2) != 3: - raise ValueError("Cross product is only defined for 3D vectors.") - - return [ - v1[1] * v2[2] - v1[2] * v2[1], - v1[2] * v2[0] - v1[0] * v2[2], - v1[0] * v2[1] - v1[1] * v2[0] - ] - -def angle_between_vectors(v1, v2): - """ - Calculate the angle (in radians) between two vectors. - - Args: - v1 (list of int/float): First vector. - v2 (list of int/float): Second vector. - - Returns: - float: The angle in radians between the two vectors. - - Raises: - ValueError: If the dimensions of the two vectors are not the same. - - Example: - >>> v1 = [1, 0] - >>> v2 = [0, 1] - >>> angle_between_vectors(v1, v2) - 1.5707963267948966 # (90 degrees in radians) - """ - if len(v1) != len(v2): - raise ValueError("The dimensions of the two vectors must be the same.") - - dot_prod = dot_product(v1, v2) - mag_v1 = vector_magnitude(v1) - mag_v2 = vector_magnitude(v2) - - return math.acos(dot_prod / (mag_v1 * mag_v2)) - -def projection(v1, v2): - """ - Project vector v1 onto vector v2. - - Args: - v1 (list of int/float): First vector. - v2 (list of int/float): Second vector. - - Returns: - list of float: The projection of v1 onto v2. - - Raises: - ValueError: If the dimensions of the two vectors are not the same. - - Example: - >>> v1 = [1, 2, 3] - >>> v2 = [4, 5, 6] - >>> projection(v1, v2) - [0.6623376623376623, 0.827922077922078, 0.9935064935064936] - """ - if len(v1) != len(v2): - raise ValueError("The dimensions of the two vectors must be the same.") - - dot_prod = dot_product(v1, v2) - mag_v2_squared = vector_magnitude(v2) ** 2 - - scalar_proj = dot_prod / mag_v2_squared - - return scalar_multiplication(v2, scalar_proj) - -# Example usage -if __name__ == "__main__": - v1 = [1, 2, 3, 4] - v2 = [4, 5, 6, 5] - - print("Vector Addition:", vector_addition(v1, v2)) - print("Vector Subtraction:", vector_subtraction(v1, v2)) - print("Dot Product:", dot_product(v1, v2)) - # print("Cross Product:", cross_product(v1, v2)) - print("Angle Between Vectors:", angle_between_vectors(v1, v2)) - print("Projection of v1 onto v2:", projection(v1, v2)) diff --git a/pysnippets/maths/fibonacci_sequence.py b/pysnippets/maths/fibonacci_sequence.py deleted file mode 100644 index 42295ab..0000000 --- a/pysnippets/maths/fibonacci_sequence.py +++ /dev/null @@ -1,217 +0,0 @@ -def fibonacci_sequence(count=None, max_value=None): - """ - Generate a Fibonacci sequence up to a specified count or maximum value. - - Args: - count (int, optional): Number of Fibonacci numbers to generate. - max_value (int, optional): Maximum value of Fibonacci numbers. - - Returns: - list: List of Fibonacci numbers. - """ - if count is None and max_value is None: - raise ValueError("Either 'count' or 'max_value' must be provided.") - - if count is not None and count <= 0: - raise ValueError("'count' must be a positive integer.") - - if max_value is not None and max_value < 0: - raise ValueError("'max_value' must be a non-negative integer.") - - sequence = [] - a, b = 0, 1 - - while (count is None or len(sequence) < count) and (max_value is None or a <= max_value): - sequence.append(a) - a, b = b, a + b - - return sequence - -def fibonacci_recursive(n): - """ - Generate the nth Fibonacci number using recursion. - - Args: - n (int): The nth Fibonacci number to generate. - - Returns: - int: The nth Fibonacci number. - """ - if n <= 1: - return n - else: - return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2) - -fib_cache = {} - -def fibonacci_memoized(n): - """ - Generate the nth Fibonacci number using recursion with memoization. - - Args: - n (int): The nth Fibonacci number to generate. - - Returns: - int: The nth Fibonacci number. - """ - if n in fib_cache: - return fib_cache[n] - - if n <= 1: - fib_cache[n] = n - else: - fib_cache[n] = fibonacci_memoized(n - 1) + fibonacci_memoized(n - 2) - - return fib_cache[n] - -def fibonacci_generator(count=None, max_value=None): - """ - Generate Fibonacci numbers as a generator. - - Args: - count (int, optional): Number of Fibonacci numbers to generate. - max_value (int, optional): Maximum value of Fibonacci numbers. - - Yields: - int: Next Fibonacci number in sequence. - """ - a, b = 0, 1 - while (count is None or count > 0) and (max_value is None or a <= max_value): - yield a - a, b = b, a + b - if count is not None: - count -= 1 - -def fibonacci_negative(n): - """ - Generate Fibonacci number for negative indices (Negafibonacci). - - Args: - n (int): Negative Fibonacci index. - - Returns: - int: Fibonacci number for the given negative index. - """ - if n == 0: - return 0 - elif n == 1: - return 1 - elif n < 0: - return (-1) ** (abs(n) + 1) * fibonacci_negative(abs(n)) - else: - return fibonacci_negative(n - 1) + fibonacci_negative(n - 2) - -def fibonacci_custom_start(a, b, count=None, max_value=None): - """ - Generate Fibonacci sequence with custom starting values. - - Args: - a (int): First number of the custom sequence. - b (int): Second number of the custom sequence. - count (int, optional): Number of Fibonacci numbers to generate. - max_value (int, optional): Maximum value of Fibonacci numbers. - - Returns: - list: Fibonacci sequence with custom start values. - """ - sequence = [a, b] - while (count is None or len(sequence) < count) and (max_value is None or sequence[-1] <= max_value): - sequence.append(sequence[-1] + sequence[-2]) - return sequence - -def fibonacci_ratio(n): - """ - Calculate the ratio of consecutive Fibonacci numbers. - - Args: - n (int): Number of Fibonacci numbers to generate. - - Returns: - list: List of ratios of consecutive Fibonacci numbers. - """ - sequence = fibonacci_sequence(count=n) - ratios = [sequence[i + 1] / sequence[i] for i in range(len(sequence) - 1) if sequence[i] != 0] - return ratios - -def fibonacci_list_or_tuple(count=None, max_value=None, return_type="list"): - """ - Generate Fibonacci sequence and return it as a list or tuple. - - Args: - count (int, optional): Number of Fibonacci numbers to generate. - max_value (int, optional): Maximum value of Fibonacci numbers. - return_type (str, optional): 'list' to return a list or 'tuple' to return a tuple. Default is 'list'. - - Returns: - list or tuple: Fibonacci sequence. - """ - sequence = fibonacci_sequence(count=count, max_value=max_value) - if return_type == "tuple": - return tuple(sequence) - return sequence - -def fibonacci_sum(count=None, max_value=None): - """ - Calculate the sum of the Fibonacci sequence. - - Args: - count (int, optional): Number of Fibonacci numbers to generate. - max_value (int, optional): Maximum value of Fibonacci numbers. - - Returns: - int: Sum of the Fibonacci sequence. - """ - sequence = fibonacci_sequence(count=count, max_value=max_value) - return sum(sequence) - -def fibonacci_module(n, mod): - """ - Generate Fibonacci sequence and return the numbers modulo a given number. - - Args: - n (int): Number of Fibonacci numbers to generate. - mod (int): Modulo value. - - Returns: - list: List of Fibonacci numbers modulo the given value. - """ - sequence = fibonacci_sequence(count=n) - return [num % mod for num in sequence] - -def nth_fibonacci(n): - """ - Generate the nth Fibonacci number. - - Args: - n (int): The nth Fibonacci number to generate. - - Returns: - int: The nth Fibonacci number. - """ - if n == 0: - return 0 - elif n == 1: - return 1 - else: - a, b = 0, 1 - for _ in range(2, n + 1): - a, b = b, a + b - return b - -if __name__ == "__main__": - - print(fibonacci_sequence(count=10)) - print(fibonacci_recursive(10)) - print(fibonacci_memoized(10)) - - for fib in fibonacci_generator(count=10): - print(fib, end=" ") - - print(fibonacci_custom_start(3, 5, count=5)) - - print(fibonacci_ratio(10)) - print(fibonacci_list_or_tuple(count=5, return_type="tuple")) - - print(fibonacci_sum(count=10)) - print(fibonacci_module(10, 3)) - print(nth_fibonacci(10)) diff --git a/pysnippets/maths/pascals_triangle.py b/pysnippets/maths/pascals_triangle.py deleted file mode 100644 index 2ddca32..0000000 --- a/pysnippets/maths/pascals_triangle.py +++ /dev/null @@ -1,162 +0,0 @@ -def pascals_triangle(rows): - """ - Generate Pascal's Triangle up to a given number of rows. - - Args: - rows (int): The number of rows to generate in Pascal's Triangle. - - Returns: - list of lists: Pascal's Triangle as a list of rows, where each row is a list of integers. - """ - if rows <= 0: - raise ValueError("'rows' must be a positive integer.") - triangle = [] - - for i in range(rows): - row = [1] * (i + 1) - for j in range(1, i): - row[j] = triangle[i - 1][j - 1] + triangle[i - 1][j] - triangle.append(row) - - return triangle - -def get_pascals_triangle_row(n): - """ - Get a specific row from Pascal's Triangle. - - Args: - n (int): The index of the row to retrieve (0-based index). - - Returns: - list: The nth row of Pascal's Triangle. - """ - if n < 0: - raise ValueError("n' must be a non-negative integer.") - row = [1] - for k in range(1, n + 1): - row.append(row[-1] * (n - k + 1) // k) - return row - -def binomial_coefficient(n, k): - """ - Calculate the binomial coefficient (n choose k) using Pascal's Triangle. - - Args: - n (int): The number of items. - k (int): The number of items to choose. - - Returns: - int: The binomial coefficient. - """ - if k < 0 or k > n: - raise ValueError("'k' must be between 0 and 'n' ") - row = get_pascals_triangle_row(n) - return row[k] - -def print_pascal_triangle(rows): - """ - Print Pascal's Triangle in a triangular format. - - Args: - rows (int): The number of rows to print. - """ - triangle = pascals_triangle(rows) - for row in triangle: - print(' '.join(map(str, row)).center(2 * rows)) - -def sum_pascals_triangle_row(n): - """ - Calculate the sum of elements in the nth row of Pascal's Triangle. - - Args: - n (int): The index of the row. - - Returns: - int: The sum of the elements in the nth row. - """ - return 2 ** n - -def factorial(n): - """ - Calculate the factorial of a number. - - Args: - n (int): The number to calculate the factorial for. - - Returns: - int: The factorial of the number. - """ - if n < 0: - raise ValueError("'n' must be non-negative integer.") - result = 1 - for i in range(2, n + 1): - result *= i - return result - -def polynomial_expansion(a, b, n): - """ - Expand the binomial expression (a + b)^n using Pascal's Triangle. - - Args: - a (int): The coefficient of the first term. - b (int): The coefficient of the second term. - n (int): The power to which the binomial is raised. - - Returns: - str: The expanded form of the binomial expression. - """ - row = get_pascals_triangle_row(n) - terms = [] - for k in range(n + 1): - coefficient = row[k] - term = f"{coefficient}*{a}^{n - k}*{b}^{k}" - terms.append(term) - return ' + '.join(terms) - - -def pascals_triangle_modulo(rows, mod): - """ - Generate Pascal's Triangle with elements modulo a given number. - - Args: - rows (int): The number of rows to generate in Pascal's Triangle. - mod (int): The number for modulo operation. - - Returns: - list of lists: Pascal's Triangle with each element modulo the given number. - """ - triangle = pascals_triangle(rows) - return [[element % mod for element in row] for row in triangle] - - -if __name__ == "__main__": - rows = 5 - - triangle = pascals_triangle(rows) - for row in triangle: - print(row) - - nth_rows = get_pascals_triangle_row(4) - print(f"4th row of Pascal's Triangle: {nth_rows}") - - bin_coeff = binomial_coefficient(5, 2) - print(f"Binomial coefficient (5 choose 2): {bin_coeff}") - - print("Pascal's triangle printed:") - print_pascal_triangle(5) - - sum_row = sum_pascals_triangle_row(4) - print(f"Sum of elements in the 4th row: {sum_row}") - - fact = factorial(5) - print(f"Factorial of 5: {fact}") - - expansion = polynomial_expansion(2, 3, 4) - print(f"Polynomial expansion of (2 + 3)^4: {expansion}") - - mod_triangle = pascals_triangle_modulo(5, 3) - print(f"Pascal's triangle modulo 3 with 5 rows") - for row in mod_triangle: - print(row) - - \ No newline at end of file