Source code for pysorting.utils

import time
from tabulate import tabulate


[docs] class InvalidElementTypeError(Exception): """Custom exception raised when elements are not strings or lists of strings.""" def __init__( self, message="All elements must be either a string or a list of strings." ): self.message = message super().__init__(self.message)
[docs] class NonUniformTypeError(Exception): """Custom exception raised when elements are not strings or lists of strings.""" def __init__(self, message="Elements are not of the same type."): self.message = message super().__init__(self.message)
[docs] class InvalidAscendingTypeError(Exception): """Custom exception raised when 'ascending' is not a boolean.""" def __init__(self, message="The parameter 'ascending' must be a boolean value."): self.message = message super().__init__(self.message)
[docs] def timer(func): """This function is used as a wrapper to time sorting function. It prints the time Parameters ---------- func : _type_ _description_ """ def wrapper(*args, **kwargs): start_time = time.time() # Record the start time result = func(*args, **kwargs) # Call the function end_time = time.time() # Record the end time elapsed_time = end_time - start_time # Calculate elapsed time print(f"Function '{func.__name__}' executed in {elapsed_time:.6f} seconds.") return result, elapsed_time # Return the result and the time taken return wrapper
[docs] def sorting_time(sorting_function, data): """ Returns the time taken to sort a function. Parameters: - sorting_function: Sorting function to output the time taken to sort. - test_data: List to sort (same data will be passed to all functions). Returns: - A tuple (fastest_function, fastest_time). """ wrapped_func = timer(sorting_function) _, elapsed_time = wrapped_func(data[:]) return elapsed_time
[docs] def find_fastest_sorting_function(data, *sorting_functions): """ Finds the fastest sorting function based on execution time. Parameters: - sorting_functions: List of sorting functions to compare. - test_data: List to sort (same data will be passed to all functions). Returns: - A tuple (fastest_function, fastest_time). """ results = [] for func in sorting_functions: # Wrap the function with the timer wrapped_func = timer(func) _, elapsed_time = wrapped_func( data[:] ) # Pass a copy of the data to avoid side effects results.append((func, elapsed_time)) # Find the function with the minimum elapsed time fastest_function, fastest_time = min(results, key=lambda x: x[1]) list_dict = { "Function": [x[0].__name__ for x in results], "Time take": [f"{x[1]:.10f}" for x in results], } print(tabulate(list_dict, headers="keys", tablefmt="fancy_grid")) return fastest_function, fastest_time
[docs] def is_sorted(lst, ascending=True): """ Checks if a list is sorted in ascending or descending order. Parameters: - lst (list): The list to check. - ascending (bool): If True, checks for ascending order; otherwise, descending. Returns: - bool: True if the list is sorted in the specified order, False otherwise. """ if ascending: return all(lst[i] <= lst[i + 1] for i in range(len(lst) - 1)) else: return all(lst[i] >= lst[i + 1] for i in range(len(lst) - 1))
[docs] def validate_list_elements(elements): """ Validates if all elements in a list are either all numerical (int or float) or all strings. Parameters: - elements (list): List of elements to validate. Returns: - bool: True if the list is valid, False otherwise. """ if all(isinstance(e, (int, float)) for e in elements): return True # All elements are numerical elif all(isinstance(e, str) for e in elements): return True # All elements are strings else: return False