Skip to content

Base

parse_int_list(value, format_func=lambda x: str(x), all_values=None)

Takes in a value or list of values e.g. [1, 2, 3] and converts it into a list of strings where each string has the format given by format_func e.g. ['1', '2', '3'] for the default case.

There are three string options for value:

  • value='x:y', will return all integers between x and y inclusive.
  • value='firstX' will return first X values of all_values.
  • value='firstY' will return first Y values of all_values.

Parameters:

Name Type Description Default
value Union[str, int, List]

Variable to convert into list of strings

required
format_func Callable

How to format each integer within the string.

lambda x: str(x)
all_values Optional[List]

List of all possible integers, must be provided if value='firstX' or value='firstY'.

None

Returns:

Type Description
List

List, where each integer in value is converted using format_func.

Source code in climdyn_tools/utils/base.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
def parse_int_list(value: Union[str, int, List], format_func: Callable = lambda x: str(x),
                   all_values: Optional[List] = None) -> List:
    """
    Takes in a value or list of values e.g. `[1, 2, 3]` and converts it into a list of strings where
    each string has the format given by `format_func` e.g. `['1', '2', '3']` for the default case.

    There are three string options for `value`:

    * `value='x:y'`, will return all integers between `x` and `y` inclusive.
    * `value='firstX'` will return first X values of `all_values`.
    * `value='firstY'` will return first Y values of `all_values`.

    Args:
        value: Variable to convert into list of strings
        format_func: How to format each integer within the string.
        all_values: List of all possible integers, must be provided if `value='firstX'` or `value='firstY'`.

    Returns:
        List, where each integer in `value` is converted using `format_func`.
    """
    if isinstance(value, list):
        pass
    elif isinstance(value, int):
        value = [value]
    elif isinstance(value, str):
        value = value.strip()       # remove blank space
        # Can specify just first or last n years
        if re.search(r'^first(\d+)', value):
            if all_values is None:
                raise ValueError(f'With value={value}, must provide all_values')
            n_req = int(re.search(r'^first(\d+)', value).group(1))
            if n_req > len(all_values):
                warnings.warn(f"Requested {value} but there are only "
                              f"{len(all_values)} available:\n{all_values}")
            value = all_values[:n_req]
        elif re.search(r'^last(\d+)', value):
            if all_values is None:
                raise ValueError(f'With value={value}, must provide all_values')
            n_req = int(re.search(r'^last(\d+)', all_values).group(1))
            if n_req > len(all_values):
                warnings.warn(f"Requested {value} but there are only "
                              f"{len(all_values)} available:\n{all_values}")
            value = all_values[-n_req:]
        elif ':' in value:
            # If '1979:2023' returns all integers from 1979 to 2023
            start, end = map(int, value.split(':'))
            value = list(range(start, end + 1))
        else:
            value = [int(value)]
    else:
        raise ValueError(f"Unsupported format: {value}")
    return [format_func(i) for i in value]

round_any(x, base, round_type='round')

Rounds x to the nearest multiple of base with the rounding done according to round_type.

Parameters:

Name Type Description Default
x Union[float, ndarray]

Number or array to round.

required
base float

Rounds x to nearest integer multiple of value of base.

required
round_type str

One of the following, indicating how to round x:

  • 'round'
  • 'ceil'
  • 'float'
'round'

Returns:

Type Description
Union[float, ndarray]

Rounded version of x.

Example
round_any(3, 5) = 5
round_any(3, 5, 'floor') = 0
Source code in climdyn_tools/utils/base.py
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
def round_any(x: Union[float, np.ndarray], base: float, round_type: str = 'round') -> Union[float, np.ndarray]:
    """
    Rounds `x` to the nearest multiple of `base` with the rounding done according to `round_type`.

    Args:
        x: Number or array to round.
        base: Rounds `x` to nearest integer multiple of value of `base`.
        round_type: One of the following, indicating how to round `x`:

            - `'round'`
            - `'ceil'`
            - `'float'`

    Returns:
        Rounded version of `x`.

    Example:
        ```
        round_any(3, 5) = 5
        round_any(3, 5, 'floor') = 0
        ```
    """
    if round_type == 'round':
        return base * np.round(x / base)
    elif round_type == 'ceil':
        return base * np.ceil(x / base)
    elif round_type == 'floor':
        return base * np.floor(x / base)
    else:
        raise ValueError(f"round_type specified was {round_type} but it should be one of the following:\n"
                         f"round, ceil, floor")

split_list_max_n(lst, n)

Split lst into balanced chunks with at most n elements each.

Parameters:

Name Type Description Default
lst Union[List, ndarray]

List to split.

required
n int

Maximum number of elements in each chunk of lst.

required

Returns:

Type Description
List

List of n chunks of lst

Source code in climdyn_tools/utils/base.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
def split_list_max_n(lst: Union[List, np.ndarray], n: int) -> List:
    """
    Split `lst` into balanced chunks with at most `n` elements each.

    Args:
        lst: List to split.
        n: Maximum number of elements in each chunk of `lst`.

    Returns:
        List of `n` chunks of `lst`
    """
    k = int(np.ceil(len(lst) / n))  # Number of chunks needed
    avg = int(np.ceil(len(lst) / k))
    return [lst[i * avg : (i + 1) * avg] for i in range(k)]