Source code for hikari.utility.list_tools

"""
This file contains tools to work with tuples and lists used in the package.
"""

from typing import Sequence

from .typing import Number

import numpy as np


[docs] def find_best(strings: list[str], criteria: str) -> str: """ Parse a list of `strings` and return the "best" element based on `criteria`. :param strings: List of string where best will be found based on `criteria`. :type strings: list[str] :param criteria: '>'-separated substrings sought in descending order. '+' is a logical 'and', '=' substitutes: `A=B` returns B if A is found. :type criteria: str :return: Best string based on given `criteria` or `` if no best found. :rtype: str """ criterion, _, further_criteria = criteria.partition('>') wanted = criterion.partition('=')[0].split('+') if all(w in strings or w == '' for w in wanted): return criterion.rpartition('=')[2] else: return find_best(strings, further_criteria)
[docs] def cubespace( start: Number, stop: Number = False, num: int = 10, include_start: bool = True, ): """ Return sequence of *num* floats between *start* and *stop*. Analogously to numpy's linspace, values in returned list are chosen so that their cubes (hence name) are spread evenly in equal distance. If the parameter *stop* is not given, the value of *start* is used as the upper limit instead. In such case the lower limit is set to 0. The values of lower limit, *start*, and upper limit, *stop*, are included in the list. The *start* value can be excluded by setting the *include_start* keyword to False. :example: >>> cubespace(10, num=3) array([ 0. , 7.93700526, 10. ]) >>> cubespace(0, -10, num=3) array([ 0. , -7.93700526, -10. ]) >>> cubespace(0, 10, num=3, include_start=False) array([ 6.93361274, 8.73580465, 10. ]) :param start: The starting value of a sequence. :type start: float :param stop: The ending value of a sequence. If False (default), *start* is used as the ending value, while the starting value is set to 0. :type stop: float :param num: Number of samples to generate. Default is 10. :type num: int :param include_start: If False, the value of *start* is not included in returned list. Nonetheless, it is still considered as a starting point. :type include_start: bool :return: An array with *num* spaced samples in the *start*-*stop* interval. :rtype: numpy.ndarray """ (start, stop) = (0.0, start) if stop is False else (start, stop) if include_start is False: return cubespace(start, stop, num=num+1, include_start=True)[1:] cubed_start = pow(start, 3) cubed_stop = pow(stop, 3) cubed_space = np.linspace(cubed_start, cubed_stop, num) return np.sign(cubed_space) * np.power(abs(cubed_space), 1/3)
[docs] def rescale_list_to_range(original: Sequence, limits: Sequence) -> list: """ Linearly rescale values in original list to limits (minimum and maximum). :example: >>> rescale_list_to_range([1, 2, 3], (0, 10)) [0.0, 5.0, 10.0] >>> rescale_list_to_range([1, 2, 3], (-10, 0)) [-10.0, -5.0, 0.0] >>> rescale_list_to_range([1, 2, 3], (0j, 10j)) [0j, 5j, 10j] :param original: Original list or list-like to be rescaled. :type original: list :param limits: Sequence of two floats, min and max, to constrain the new list :type limits: Sequence :return: Original list rescaled to fit between min and max :rtype: list """ original = np.array(original) new_min, new_max = limits[0:2] old_min, old_max = min(original), max(original) return (new_max + new_min) / 2 * original / old_min if old_min == old_max \ else list((new_max * (original - old_min) / (old_max - old_min) + new_min * (old_max - original) / (old_max - old_min)))
[docs] def rescale_list_to_other(source: Sequence, target: Sequence) -> list: """ Linearly rescale *source* list of numeral values to elements of iterable scale in *target*. The numeric values in the first list are rescaled to the length of *other* using :func:`rescale_list_to_range`, changed to integers and used as pointers in *other* to retrieve final value. :example: >>> rescale_list_to_other([1, 2, 3], [-7.7, -6.6, -5.5, -4.4, -3.3]) [-7.7, -5.5, -3.3] >>> rescale_list_to_other([-7.7, -6.6, -5.5, -4.4, -3.3], [1, 2, 3]) [1, 1, 2, 3, 3] >>> rescale_list_to_other([1, 2, 3], 'holy grail') ['h', ' ', 'l'] :param source: Sequence of numerals to be rescaled to *other*. :type source: Sequence :param target: Sequence from which the values in new list will be selected. :type target: Sequence :return: List with elements from *other* assigned using values in original. :rtype: list """ return [target[int(v)] for v in rescale_list_to_range(original=source, limits=(0, len(target)-1))]