diff --git a/automol/util/_util.py b/automol/util/_util.py index 900aa2c5..aa564f2f 100644 --- a/automol/util/_util.py +++ b/automol/util/_util.py @@ -24,8 +24,9 @@ def partner(pair: Collection, item: Any) -> Any: def flatten(lst: Collection) -> Iterator: """Flatten an arbitrarily nested list of lists (iterator). - - Source: https://stackoverflow.com/a/2158532 + Source: https://stackoverflow.com/a/2158532 . + :param lst: An arbitrarily nested list or tuple + :return: An iterator over the flattened list of values """ for elem in lst: if isinstance(elem, Iterable) and not isinstance(elem, str | bytes): @@ -72,7 +73,7 @@ def is_odd_permutation(seq1: list, seq2: list) -> bool: return not is_even_permutation(seq1, seq2) -def is_even_permutation(seq1: list, seq2: list, check: bool = True) -> bool: +def is_even_permutation(seq1: Sequence, seq2: Sequence, check: bool = True) -> bool: """Determine whether a permutation of a sequence is even. :param seq1: The first sequence @@ -189,10 +190,12 @@ def move_items_to_front(lst: Sequence, items) -> tuple: return tuple(lst) -def breakby(lst: Collection, elem) -> tuple[tuple, tuple]: +def breakby(lst: Sequence, elem) -> tuple[tuple, tuple]: """Break a list by element, dropping the element itself. - Analogous to ''.split('') for strings. + :param lst: The list + :param elem: The element to break the list by, gets deleted + :return:The chunks between the break points of the input list """ lsts = tuple( tuple(g) for k, g in itertools.groupby(lst, lambda x: x == elem) if not k @@ -200,23 +203,35 @@ def breakby(lst: Collection, elem) -> tuple[tuple, tuple]: return lsts -def separate_negatives(lst: Sequence): - """Seperate a list of numbers into negative and nonnegative (>= 0).""" +def separate_negatives(lst: Sequence)-> tuple [tuple,tuple]: + """Seperate a list of numbers into negative and nonnegative (>= 0). + :param lst: The list + :return: Value for negatives and for positives. + """ neg_lst = tuple(val for val in lst if val < 0) pos_lst = tuple(val for val in lst if val >= 0) return neg_lst, pos_lst -def value_similar_to(val: float, lst: Collection[float], thresh: float) -> bool: - """Check if a value is close to some lst of values within some threshold.""" +def value_similar_to(val: float, lst: Sequence[float], thresh: float) -> bool: + """Check if a value is close to any one of a list of values. + :param val: A number. + :param lst: A collection of numbers to compare to. + :param thresh: The comparison threshold. + :return: 'True' if close, 'False' if not. + """ return any(abs(val - vali) < thresh for vali in lst) def scale_iterable( iterable: Collection[float], scale_factor: float ) -> Collection[float]: - """Scale some type of iterable of floats by a scale factor.""" + """Scale some type of iterable of floats by a scale factor. + :param iterable: A list of numbers. + :param scale_factor: A factor to scale by. + :return: + """ if isinstance(iterable, list): iterable = [val * scale_factor for val in iterable] elif isinstance(iterable, tuple): diff --git a/automol/util/ring.py b/automol/util/ring.py index a8067220..fa0c9057 100644 --- a/automol/util/ring.py +++ b/automol/util/ring.py @@ -1,19 +1,11 @@ -r"""Functions for dealing with a list of items encoding a ring - - 1---2 - / \ - [1, 2, 3, 4, 5, 6] <=> 6 3 - \ / - 5---4 -""" +"""Functions for dealing with a list of items encoding a ring.""" import itertools -from typing import List, Tuple import more_itertools as mit -def normalize(items: List[object]) -> List[object]: +def normalize(items: list[object]) -> list[object]: """Normalize the ordering of items in a ring. :param items: The ring items @@ -28,7 +20,7 @@ def normalize(items: List[object]) -> List[object]: return cycle(items, count=items.index(start_item)) -def cycle(items: List[object], count: int = 1) -> List[object]: +def cycle(items: list[object], count: int = 1) -> list[object]: """Cycle ring items once. Example: (1, 2, 3, 4) -> (2, 3, 4, 1) @@ -42,7 +34,7 @@ def cycle(items: List[object], count: int = 1) -> List[object]: return tuple(itertools.islice(cycler, nitems)) -def edges(items: List[object]) -> List[object]: +def edges(items: list[object]) -> list[object]: """Get the edge pairs of a ring. Example: (1, 2, 3, 4) -> ((1, 2), (2, 3), (3, 4), (4, 1)) @@ -54,23 +46,18 @@ def edges(items: List[object]) -> List[object]: def distance( - items: List[object], item1: object, item2: object, longest: bool = False + items: list[object], item1: object, item2: object, longest: bool = False ) -> int: - """Find the distance between two items in a ring + """Find the distance between two items in a ring. By default, finds the shortest distance. Setting `longest=True` results in the longest distance. :param items: The ring items - :type items: List[object] :param item1: The item to start measuring distance from - :type item1: object :param item2: The item to measure distance to - :type item2: object :param longest: Return the longest distance?, defaults to False - :type longest: bool, optional :return: The number of ring items between these two - :rtype: int """ assert ( item1 in items and item2 in items @@ -95,17 +82,15 @@ def distance( def cycle_item_to_front( - items: List[object], item: object, end_item: object = None -) -> List[object]: - """Cycle ring items until one is in front + items: list[object], item: object, end_item: object = None +) -> list[object]: + """Cycle ring items until one is in front. Optionally, request one adjacent item to be at the end, reversing the ring order if necessary. :param items: The ring items - :type items: List[object] :parm item: The item to cycle to the font - :type item: object :param end_item: optionally, ensure that this is the last item in the ring :type end_item: object :returns: The ring items with `item` cycled to the front and `end_item` to the end @@ -124,16 +109,13 @@ def cycle_item_to_front( def cycle_items_to_front( - items: List[object], front_items: List[object] -) -> List[object]: - """Cycle ring items until a group of adjacent items is at the front of the list + items: list[object], front_items: list[object] +) -> list[object]: + """Cycle ring items until a group of adjacent items is at the front of the list. :param items: The ring items - :type items: List[object] :parm front_items: The item to cycle to the font - :type front_items: List[object] :returns: The ring items with `item` cycled to the front and `end_item` to the end - :rtype: List[int] """ nitems = len(items) @@ -149,8 +131,8 @@ def cycle_items_to_front( return tuple(itertools.islice(cycler, nitems)) -def cycle_items_to_back(items: List[object], back_items: List[object]) -> List[object]: - """Cycle ring items until a group of adjacent items is at the end of the list +def cycle_items_to_back(items: list[object], back_items: list[object]) -> list[object]: + """Cycle ring items until a group of adjacent items is at the end of the list. :param items: The ring items :type items: List[object] @@ -174,9 +156,9 @@ def cycle_items_to_back(items: List[object], back_items: List[object]) -> List[o def cycle_to_split( - items: List[object], split_pair: Tuple[object, object] -) -> List[object]: - """Cycle to split a pair of adjacent items, putting one on each end of the list + items: list[object], split_pair: tuple[object, object] +) -> list[object]: + """Cycle to split a pair of adjacent items, putting one on each end of the list. :param items: The ring items :type items: List[object] @@ -211,12 +193,12 @@ def cycle_to_split( def cycle_to_optimal_split( - items: List[object], - split_pairs: List[Tuple[object, object]], - back_items: List[object], -) -> List[object]: + items: list[object], + split_pairs: list[tuple[object, object]], + back_items: list[object], +) -> list[object]: """Cycle to find an "optimum split" that puts a subset of items as close as possible - to the end of the list + to the end of the list. :param items: The ring items :type items: List[object] diff --git a/docs/source/automol/ring.md b/docs/source/automol/ring.md new file mode 100644 index 00000000..98e7ce33 --- /dev/null +++ b/docs/source/automol/ring.md @@ -0,0 +1,5 @@ +# automol.ring +some words +```{eval-rst} +.. automodule:: automol.util.ring +``` \ No newline at end of file diff --git a/docs/source/index.md b/docs/source/index.md index 097e8cc0..913b0ec7 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -8,4 +8,5 @@ automol/inchi_key.md automol/util.md automol/heuristic.md automol/matrix.md +automol/ring.md ``` diff --git a/lint.sh b/lint.sh index c908c4e9..e445b70b 100755 --- a/lint.sh +++ b/lint.sh @@ -7,6 +7,7 @@ FILES=( "automol/util/__init__.py" "automol/util/heuristic.py" "automol/util/matrix.py" + "automol/util/ring.py" ) (