From 80b1c7518e7eb6ebba305d9b105460d6bde22a51 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Fri, 5 Jan 2024 20:04:30 +0200 Subject: [PATCH] docs(ai): add docstrings --- src/ai/fitness/bumpiness.py | 13 +++++++++++++ src/ai/fitness/calculate.py | 9 +++++++++ src/ai/fitness/holes.py | 23 +++++++++++++++++++++++ src/ai/fitness/peaks.py | 35 +++++++++++++++++++++++++++++++++++ src/ai/fitness/transitions.py | 20 ++++++++++++++++++++ src/ai/fitness/wells.py | 26 ++++++++++++++++++++++++++ 6 files changed, 126 insertions(+) diff --git a/src/ai/fitness/bumpiness.py b/src/ai/fitness/bumpiness.py index 9e40146..71fcb33 100644 --- a/src/ai/fitness/bumpiness.py +++ b/src/ai/fitness/bumpiness.py @@ -8,6 +8,19 @@ from .peaks import get_peaks def get_bumpiness( *, peaks: Optional[np.ndarray] = None, field: Optional[np.ndarray] = None ) -> int: + """ + Calculate the bumpiness of a given signal based on peaks. + + Args: + peaks: Array containing peak indices. If not provided, it will be computed from the field. + field: The signal field. Required if peaks is not provided. + + Returns: + The bumpiness of the signal. + + Raises: + ValueError: If both `peaks` and `field` are `None`. + """ if peaks is None and field is None: raise ValueError("peaks and field cannot both be None") elif peaks is None: diff --git a/src/ai/fitness/calculate.py b/src/ai/fitness/calculate.py index 93e8743..f5c5b4a 100644 --- a/src/ai/fitness/calculate.py +++ b/src/ai/fitness/calculate.py @@ -12,6 +12,15 @@ from .wells import get_wells, get_wells_max def calculate_fitness(field: np.ndarray) -> float: + """ + Calculate the fitness value for the given field. + + Args: + field: The game field. + + Returns: + The fitness value. + """ peaks = get_peaks(field=field) holes = get_holes(field=field) highest_peak = get_peaks_max(peaks=peaks) diff --git a/src/ai/fitness/holes.py b/src/ai/fitness/holes.py index b647d99..c242385 100644 --- a/src/ai/fitness/holes.py +++ b/src/ai/fitness/holes.py @@ -9,6 +9,16 @@ def get_holes( field: np.ndarray, peaks: Optional[np.array] = None, ) -> np.array: + """ + Calculate the number of holes in each column of the given field. + + Args: + field: The signal field. + peaks: Array containing peak indices. If not provided, it will be computed from the field. + + Returns: + Array containing the number of holes in each column. + """ if peaks is None: peaks = get_peaks(field) col_count = field.shape[1] @@ -25,6 +35,19 @@ def get_holes( def get_holes_sum( *, holes: Optional[np.ndarray] = None, field: Optional[np.ndarray] = None ) -> int: + """ + Calculate the total number of holes in the given field or use pre-computed holes. + + Args: + holes: Array containing the number of holes in each column. If not provided, it will be computed from the field. + field: The signal field. Required if holes is not provided. + + Returns: + The total number of holes in the field. + + Raises: + ValueError: If both `holes` and `field` are `None`. + """ if holes is None and field is None: raise ValueError("holes and field cannot both be None") elif holes is None: diff --git a/src/ai/fitness/peaks.py b/src/ai/fitness/peaks.py index d16c026..2d3b976 100644 --- a/src/ai/fitness/peaks.py +++ b/src/ai/fitness/peaks.py @@ -4,6 +4,15 @@ import numpy as np def get_peaks(field: np.ndarray) -> np.ndarray: + """ + Find the peaks in each column of the given field. + + Args: + field: The signal field. + + Returns: + Array containing the indices of the peaks in each column. + """ peaks = np.where(field == 1, field.shape[0] - np.argmax(field, axis=0), 0) return peaks.max(axis=0) @@ -11,6 +20,19 @@ def get_peaks(field: np.ndarray) -> np.ndarray: def get_peaks_max( *, peaks: Optional[np.ndarray] = None, field: Optional[np.ndarray] = None ) -> int: + """ + Get the maximum peak value from the provided peaks or compute peaks from the field. + + Args: + peaks: Array containing the indices of the peaks in each column. If not provided, it will be computed from the field. + field: The signal field. Required if peaks is not provided. + + Returns: + The maximum peak value. + + Raises: + ValueError: If both `peaks` and `field` are `None`. + """ if peaks is None and field is None: raise ValueError("peaks and field cannot both be None") elif peaks is None: @@ -21,6 +43,19 @@ def get_peaks_max( def get_peaks_sum( *, peaks: Optional[np.ndarray] = None, field: Optional[np.ndarray] = None ) -> int: + """ + Get the sum of peak values from the provided peaks or compute peaks from the field. + + Args: + peaks: Array containing the indices of the peaks in each column. If not provided, it will be computed from the field. + field: The signal field. Required if peaks is not provided. + + Returns: + The sum of peak values. + + Raises: + ValueError: If both `peaks` and `field` are `None`. + """ if peaks is None and field is None: raise ValueError("peaks and field cannot both be None") elif peaks is None: diff --git a/src/ai/fitness/transitions.py b/src/ai/fitness/transitions.py index ba9bf9b..4a9721c 100644 --- a/src/ai/fitness/transitions.py +++ b/src/ai/fitness/transitions.py @@ -6,6 +6,16 @@ from .peaks import get_peaks, get_peaks_max def get_row_transition(field: np.ndarray, highest_peak: Optional[int] = None) -> int: + """ + Calculate the number of transitions in the rows of the given field. + + Args: + field: The signal field. + highest_peak: The highest peak value. If not provided, it will be computed from the field. + + Returns: + The total number of transitions in the rows. + """ if highest_peak is None: highest_peak = get_peaks_max(field=field) @@ -16,6 +26,16 @@ def get_row_transition(field: np.ndarray, highest_peak: Optional[int] = None) -> def get_col_transition(field: np.ndarray, peaks: Optional[np.ndarray] = None) -> int: + """ + Calculate the number of transitions in the columns of the given field. + + Args: + field: The signal field. + peaks: Array containing the indices of the peaks in each column. If not provided, it will be computed from the field. + + Returns: + The total number of transitions in the columns. + """ if peaks is None: peaks = get_peaks(field) diff --git a/src/ai/fitness/wells.py b/src/ai/fitness/wells.py index 84bee60..06acebc 100644 --- a/src/ai/fitness/wells.py +++ b/src/ai/fitness/wells.py @@ -10,6 +10,19 @@ from .peaks import get_peaks def get_wells( *, peaks: Optional[np.ndarray] = None, field: Optional[np.ndarray] = None ) -> np.ndarray: + """ + Calculate the well depths in each column of the given field. + + Args: + peaks: Array containing the indices of the peaks in each column. If not provided, it will be computed from the field. + field: The signal field. Required if peaks is not provided. + + Returns: + Array containing the well depths in each column. + + Raises: + ValueError: If both `peaks` and `field` are `None`. + """ if peaks is None and field is None: raise ValueError("peaks and field cannot both be None") elif peaks is None: @@ -38,6 +51,19 @@ def get_wells( def get_wells_max( *, wells: Optional[np.ndarray] = None, field: Optional[np.ndarray] = None ) -> int: + """ + Get the maximum well depth from the provided wells or compute wells from the field. + + Args: + wells: Array containing the well depths in each column. If not provided, it will be computed from the field. + field: The signal field. Required if wells is not provided. + + Returns: + The maximum well depth. + + Raises: + ValueError: If both `wells` and `field` are `None`. + """ if wells is None and field is None: raise ValueError("wells and field cannot both be None") elif wells is None: