Skip to content

Commit

Permalink
more _util cleaning and ring.py cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
Rosalbam1 committed Jul 10, 2024
1 parent 9063331 commit 12af840
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 50 deletions.
35 changes: 25 additions & 10 deletions automol/util/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -189,34 +190,48 @@ 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 '<char>'.split('<string>') 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
)
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):
Expand Down
62 changes: 22 additions & 40 deletions automol/util/ring.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)
Expand All @@ -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))
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)

Expand All @@ -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]
Expand All @@ -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]
Expand Down Expand Up @@ -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]
Expand Down
5 changes: 5 additions & 0 deletions docs/source/automol/ring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# automol.ring
some words
```{eval-rst}
.. automodule:: automol.util.ring
```
1 change: 1 addition & 0 deletions docs/source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ automol/inchi_key.md
automol/util.md
automol/heuristic.md
automol/matrix.md
automol/ring.md
```
1 change: 1 addition & 0 deletions lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ FILES=(
"automol/util/__init__.py"
"automol/util/heuristic.py"
"automol/util/matrix.py"
"automol/util/ring.py"
)

(
Expand Down

0 comments on commit 12af840

Please sign in to comment.