1"""Various generic useful functions
2"""
3
4
5def is_seq(o):
6    """Check if the object is a sequence.
7
8    Parameters
9    ----------
10    o : any object
11      The object to check
12
13    Returns
14    -------
15    is_seq : bool, scalar
16      True if *o* is a sequence, False otherwise
17    """
18    return hasattr(o, "__len__")
19
20
21def is_seq_of_seq(o):
22    """Check if the object is a sequence of sequences. No check is done on
23    the sizes of the sequences.
24
25    Parameters
26    ----------
27    o : any object
28      The object to check
29
30    Returns
31    -------
32    is_seq_of_seq : bool
33      True if *o* is a sequence of sequences, False otherwise.
34    """
35    if not is_seq(o):
36        return False
37    for s in o:
38        if not is_seq(s):
39            return False
40    return True
41
42
43def is_like2d(o):
44    """Check if *o* is conformable to a 2d array.
45
46    Parameters
47    ----------
48    o : any object
49      The object to check
50
51    Returns
52    -------
53    is_like2d : bool, scalar
54      True if *o* is conformable to a 2d array, False otherwise.
55    """
56    if not is_seq(o):
57        return False
58    size = None
59    for s in o:
60        if not is_seq(s):
61            return False
62        if size is None:
63            size = len(s)
64        if len(s) != size:
65            return False
66    return True
67
68
69def len_array_or_arrays(o):
70    """Returns the length of a single array or list of arrays
71
72    Parameters
73    ----------
74    o : either array or sequence of arrays
75
76    Returns
77    -------
78    length : length of array
79    """
80    if is_seq_of_seq(o):
81        length = len(o[0])
82    else:
83        length = len(o)
84    return length
85