@classmethod
def create_from(cls, vehicle):
    """
            Create a new vehicle from an existing one.
            The vehicle dynamics and target dynamics are copied, other properties are default.

        :param vehicle: a vehicle
        :return: a new vehicle at the same dynamical state
        """
    v = cls(vehicle.road, vehicle.position, heading=vehicle.heading,
        velocity=vehicle.velocity, target_lane_index=vehicle.
        target_lane_index, target_velocity=vehicle.target_velocity, route=
        vehicle.route)
    return v


def _contains(prop_value, cmp_value, ignore_case=False):
    """
    Helper function that take two arguments and checks if :param cmp_value:
    is in :param prop_value:.

    :param prop_value: Property value that you are checking.
    :type prop_value: :class:`str`
    :param cmp_value: Value that you are checking if it is in the property
        value.
    :type cmp_value: :class:`str`
    :param ignore_case: True to run using incase sensitive.
    :type ignore_case: :class:`bool`
    :returns: True if :param cmp_value: is in :param prop_value:
    :rtype: class:`bool`
    """
    if ignore_case is True:
        prop_value = prop_value.lower()
        cmp_value = cmp_value.lower()
    return cmp_value in prop_value


def getPortalPath():
    """ Return the portal object's URL without the server URL component.

        o Return a slash-delimited string.

        o Permission:  Public
        """


def bake_action(frame_start: int, frame_end: int, frame_step: int=1,
    only_selected: bool=False, do_pose: bool=True, do_object: bool=True,
    do_visual_keying: bool=True, do_constraint_clear: bool=False,
    do_parents_clear: bool=False, do_clean: bool=False, action:
    'bpy.types.Action'=None) ->'bpy.types.Action':
    """Return an image from the file path with options to search multiple paths and return a placeholder if its not found.

    :param frame_start: First frame to bake.
    :type frame_start: int
    :param frame_end: Last frame to bake.
    :type frame_end: int
    :param frame_step: Frame step.
    :type frame_step: int
    :param only_selected: Only bake selected bones.
    :type only_selected: bool
    :param do_pose: Bake pose channels.
    :type do_pose: bool
    :param do_object: Bake objects.
    :type do_object: bool
    :param do_visual_keying: Use the final transformations for baking (‘visual keying’)
    :type do_visual_keying: bool
    :param do_constraint_clear: Remove constraints after baking.
    :type do_constraint_clear: bool
    :param do_parents_clear: Unparent after baking objects.
    :type do_parents_clear: bool
    :param do_clean: Remove redundant keyframes after baking.
    :type do_clean: bool
    :param action: An action to bake the data into, or None for a new action to be created.
    :type action: 'bpy.types.Action'
    :return:  an action or None
    """
    pass


@classmethod
def _from_dict(cls, _dict):
    """Initialize a TokenDictStatusResponse object from a json dictionary."""
    args = {}
    if 'status' in _dict:
        args['status'] = _dict.get('status')
    if 'type' in _dict:
        args['type'] = _dict.get('type')
    return cls(**args)


def transform_timeseries_data(timeseries, start, end=None):
    """Transforms a Go Metrics API metric result into a list of
    values for a given window period.

    start and end are expected to be Unix timestamps in microseconds.
    """
    data = []
    include = False
    for metric, points in timeseries.items():
        for point in points:
            if point['x'] == start:
                include = True
            if include:
                data.append(point['y'])
            if end is not None and point['x'] == end:
                return data
    return data


@staticmethod
def _escape_value(value) ->str:
    """
        Formats and replaces backslashes and single quoted parenthesis
        :param value: str
        :return: str
        """
    if isinstance(value, str):
        return '{}'.format(value.replace('\\', '\\\\').replace('"', '\\"').
            replace('(', '\\(').replace(')', '\\)'))
    else:
        return value


def is_palindrome(sequence):
    """Check whether the sequence is a palindrome or not."""
    return str(sequence) == str(sequence.reverse_complement())


def process_appkey(app_key):
    """
    完美api签名计算规则之一，固定的appkey剪裁
    :param app_key:
    :return:
    """
    enc_key = app_key[2:5] + app_key[10:16] + app_key[18:20] + app_key[14:19]
    return enc_key


def smoothen(df):
    """
    Helper funciton to smooth out vacuum energy fluctuations (DFT problem).
    :param df: A DataFrame with distance and energy values.
    :return: DataFrame with smooth data.
    """
    df_new = df.copy(deep=True)
    df_new = df_new.sort_values(by='distance').reset_index(drop=True)
    for idx, entry in enumerate(df.energy):
        if idx == 0:
            previos_entry = entry
        else:
            dE = entry - previos_entry
            if dE < 0:
                df_new = df_new.drop([idx], axis=0)
            previos_entry = entry
    df_new = df_new.reset_index(drop=True)
    return df_new


def _add_doc(func, doc):
    """Add documentation to a function."""
    func.__doc__ = doc


def parse_keywords(strings=[]):
    """Parse keywords specifications from the given list of strings.

    >>> kw = sorted(parse_keywords(['_', 'dgettext:2', 'dngettext:2,3', 'pgettext:1c,2']).items())
    >>> for keyword, indices in kw:
    ...     print((keyword, indices))
    ('_', None)
    ('dgettext', (2,))
    ('dngettext', (2, 3))
    ('pgettext', ((1, 'c'), 2))
    """
    keywords = {}
    for string in strings:
        if ':' in string:
            funcname, indices = string.split(':')
        else:
            funcname, indices = string, None
        if funcname not in keywords:
            if indices:
                inds = []
                for x in indices.split(','):
                    if x[-1] == 'c':
                        inds.append((int(x[:-1]), 'c'))
                    else:
                        inds.append(int(x))
                indices = tuple(inds)
            keywords[funcname] = indices
    return keywords


def decorateTitle(title, options):
    """ Add a marker to TITLE if the TITLE is sorted on.
    """
    if title.lower() == options.sortCategory:
        return '%s*' % title
    else:
        return title


def vertices_cross(size, line_width):
    """Returns a list of vertices describing a cross.

    Notes
    -----
    The resulting vertices can be plotted with the class
    stimuli.Shape(vertex_list=...).

    Parameters
    ----------
    size : (int, int)
        xy, length of the horizontal (x) and vertical (y) line
    line_width : int
        width of the lines

    Returns
    -------
    vtx : list of vertices

    See Also
    --------
    expyriment.stimuli.FixCross

    """
    x_a = (size[0] - line_width) // 2
    x_b = x_a
    y_a = (size[1] - line_width) // 2
    y_b = y_a
    if (size[0] - line_width) % 2:
        x_b = x_a + 1
        if line_width % 2:
            x_b, x_a = x_a, x_b
    if (size[1] - line_width) % 2:
        y_b = y_a + 1
        if line_width % 2 == 0:
            y_b, y_a = y_a, y_b
    return [(line_width - 1, 0), (0, -y_a), (x_a, 0), (0, -line_width + 1),
        (-x_a, 0), (0, -y_b), (-line_width + 1, 0), (0, y_b), (-x_b, 0), (0,
        line_width - 1), (x_b, 0)]


def render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

    Like 'git describe --tags --dirty --always'.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


def __call__(cls, value):
    """Either returns an existing member, or creates a new SumType class.
        """
    return cls.__new__(cls, value)


def extend_path(conn, arguments):
    """
    get the remote environment's env so we can explicitly add the path without
    wiping out everything
    """
    try:
        result = conn.gateway.remote_exec(
            'import os; channel.send(os.environ.copy())')
        env = result.receive()
    except Exception:
        conn.logger.exception(
            'failed to retrieve the remote environment variables')
        env = {}
    path = env.get('PATH', '')
    env['PATH'
        ] = path + '/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin'
    arguments['env'] = env
    return arguments


def _is_list(list_):
    """Test if variable is a list.

    Maybe this is not the best way to test for a list, but it is sufficient for
    current use case.
    """
    try:
        len(list_)
        return True
    except TypeError:
        return False


def get_max_id(key_dict):
    """
    Gets the max id found inside a key_dict keys

    :param key_dict: Dict containing the correspondance between contigs and contig maps
    :type key_dict: dict((int, int, int), (str, int, int, int))
    :return: Maximum value of the key_dict keys
    :rtype: int
    """
    max_id = 0
    for map_id, _, _ in key_dict:
        if max_id < map_id:
            max_id = map_id
    return max_id


def plus_or_dot(pieces):
    """Return a + if we don't already have one, else return a ."""
    if '+' in pieces.get('closest-tag', ''):
        return '.'
    return '+'


def pairs(item_list):
    """
    Returns an iterator of all pairs of elements from item_list.

    :param item_list: items (no duplicates allowed)
    """
    for i, item1 in enumerate(item_list):
        for item2 in item_list[i + 1:]:
            yield item1, item2


@classmethod
def __parse_script(cls, script_data):
    """
            Private method parsing the data from NSE scripts output

            :param script_data: portion of XML describing the results of the
            script data
            :type script_data: xml.ElementTree.Element or a string

            :return: python dict holding scripts output
        """
    _script_dict = cls.__format_attributes(script_data)
    _elt_dict = {}
    for script_elem in script_data:
        if script_elem.tag == 'elem':
            _elt_dict.update({script_elem.get('key'): script_elem.text})
        elif script_elem.tag == 'table':
            tdict = {}
            for telem in script_elem:
                tkey = telem.get('key')
                if tkey in tdict:
                    if not isinstance(tdict[tkey], list):
                        tdict[tkey] = [tdict[tkey]]
                    tdict[tkey].append(telem.text)
                else:
                    tdict[tkey] = telem.text
            skey = script_elem.get('key')
            if skey in _elt_dict:
                if not isinstance(_elt_dict[skey], list):
                    _elt_dict[skey] = [_elt_dict[skey]]
                _elt_dict[skey].append(tdict)
            else:
                _elt_dict[skey] = tdict
    _script_dict['elements'] = _elt_dict
    return _script_dict


def strip_name(name):
    """
    Method that strips any |Path and :Namespaces: from a given object DAG path
    Ns:Rig|Ns:Leg|Ns:Test == Test
    :param name: str
    :return: str
    """
    return name.split('|')[-1].split(':')[-1]


def lag_spatial(w, y):
    """
    Spatial lag operator.

    If w is row standardized, returns the average of each observation's neighbors;
    if not, returns the weighted sum of each observation's neighbors.

    Parameters
    ----------

    w                   : W
                          libpysal spatial weightsobject
    y                   : array
                          numpy array with dimensionality conforming to w (see examples)

    Returns
    -------

    wy                  : array
                          array of numeric values for the spatial lag

    Examples
    --------

    Setup a 9x9 binary spatial weights matrix and vector of data; compute the
    spatial lag of the vector.

    >>> import libpysal
    >>> import numpy as np
    >>> w = libpysal.weights.lat2W(3, 3)
    >>> y = np.arange(9)
    >>> yl = libpysal.weights.lag_spatial(w, y)
    >>> yl
    array([ 4.,  6.,  6., 10., 16., 14., 10., 18., 12.])

    Row standardize the weights matrix and recompute the spatial lag

    >>> w.transform = 'r'
    >>> yl = libpysal.weights.lag_spatial(w, y)
    >>> yl
    array([2.        , 2.        , 3.        , 3.33333333, 4.        ,
           4.66666667, 5.        , 6.        , 6.        ])

    Explicitly define data vector as 9x1 and recompute the spatial lag

    >>> y.shape = (9, 1)
    >>> yl = libpysal.weights.lag_spatial(w, y)
    >>> yl
    array([[2.        ],
           [2.        ],
           [3.        ],
           [3.33333333],
           [4.        ],
           [4.66666667],
           [5.        ],
           [6.        ],
           [6.        ]])

    Take the spatial lag of a 9x2 data matrix

    >>> yr = np.arange(8, -1, -1)
    >>> yr.shape = (9, 1)
    >>> x = np.hstack((y, yr))
    >>> yl = libpysal.weights.lag_spatial(w, x)
    >>> yl
    array([[2.        , 6.        ],
           [2.        , 6.        ],
           [3.        , 5.        ],
           [3.33333333, 4.66666667],
           [4.        , 4.        ],
           [4.66666667, 3.33333333],
           [5.        , 3.        ],
           [6.        , 2.        ],
           [6.        , 2.        ]])

    """
    return w.sparse * y


@classmethod
def from_rv_discrete(cls, ssrv, prng=None):
    """
        Create a ScalarDistribution from a scipy.states.rv_discrete instance.

        Parameters
        ----------
        ssrv : scipy.stats.rv_discrete
            The random variable to convert to a dit.ScalarDistribution.
        prng : RandomState
            A pseudo-random number generator with a `rand` method which can
            generate random numbers. For now, this is assumed to be something
            with an API compatibile to NumPy's RandomState class. If `None`,
            then we initialize to dit.math.prng.

        Returns
        -------
        d : ScalarDistribution
            A ScalarDistribution representation of `ssrv`.
        """
    outcomes = ssrv.xk
    pmf = ssrv.pk
    prng = prng if prng is not None else ssrv.random_state
    return cls(outcomes, pmf, prng=prng)


def oddPeak(indx, peaks):
    """needs a doc string"""
    noOdd = True
    for peak in peaks:
        H = peak[4:7]
        if H[indx] % 2:
            noOdd = False
    return noOdd


@staticmethod
def address(token):
    """
        Convert numeric strings into memory addresses.

        @type  token: str
        @param token: String to parse.

        @rtype:  int
        @return: Parsed integer value.
        """
    return int(token, 16)


def is_kwarg(argument: str) ->bool:
    """`True` if argument name is `**kwargs`"""
    return '**' in argument


@classmethod
def calculate_penalty(cls, virtual_step_used: int, step_price: int) ->int:
    """Returns penalty according to given parameters

        :param virtual_step_used:
        :param step_price:
        """
    return virtual_step_used * step_price


@staticmethod
def get_latin_soundex(token):
    """
        Get the phoneme code for the latin word
        Args:
            token: word
        Returns:
            (str): soundex code
        Examples:
            >>> token = 'availability'
            >>> PhonemeModel().get_latin_soundex(token)
            'A181870000'
        """
    token = token.upper()
    soundex = ''
    soundex += token[0]
    dictionary = {'BPV': '1', 'F': '2', 'C': '3', 'GJ': '4', 'KQ': '5',
        'SXZ': '6', 'DT': '7', 'L': '8', 'MN': '9', 'R': '10', 'AEIOUHWY': '.'}
    for char in token[1:]:
        for key in dictionary.keys():
            if char in key:
                code = dictionary[key]
                if code != soundex[-1]:
                    soundex += code
    soundex = soundex.replace('.', '')
    soundex = soundex[:10].ljust(10, '0')
    return soundex


def bisect_find_sha(start, end, sha, unpack_name):
    """Find a SHA in a data blob with sorted SHAs.

    :param start: Start index of range to search
    :param end: End index of range to search
    :param sha: Sha to find
    :param unpack_name: Callback to retrieve SHA by index
    :return: Index of the SHA, or None if it wasn't found
    """
    assert start <= end
    while start <= end:
        i = (start + end) // 2
        file_sha = unpack_name(i)
        if file_sha < sha:
            start = i + 1
        elif file_sha > sha:
            end = i - 1
        else:
            return i
    return None


def execute(need_active: bool=False):
    """Execute selected file

    :param need_active: Need Active, Only execute if there’s an active selected file in the file list
    :type need_active: bool
    """
    pass


def strenumerate(*args, **kwargs):
    """Same as enumerate, but yields str(index)."""
    for i, v in enumerate(*args, **kwargs):
        yield str(i), v


def unread():
    """ The number of unread notifications for the current user
        """


def clear():
    """Remove all key/value pairs."""


@classmethod
def add_dimension(cls, columns, dimension, dim_pos, values, vdim):
    """
        Adding value dimensions not currently supported by iris interface.
        Adding key dimensions not possible on dense interfaces.
        """
    if not vdim:
        raise Exception('Cannot add key dimension to a dense representation.')
    raise NotImplementedError


def get_solution(tests):
    """Parse out the solution from a coding challenge test class

    Parameters
    ----------
    test : a code cell containing a test class

    There must be a `solution()` method

    """
    lines = tests.split('\n')
    i = 0
    while True:
        line = lines[i]
        if not 'def solution' in line:
            i += 1
            continue
        else:
            break
    i += 1
    solution = []
    while True:
        line = lines[i]
        if not line.strip():
            break
        solution.append(line)
        i += 1
    solution = ['```python'] + solution[:-1] + ['```']
    return solution


def status_codes_by_date_chart():
    """Chart for status codes by date."""
    return {'chart': {'type': 'area', 'zoomType': 'x'}, 'title': {'text':
        None}, 'xAxis': {'type': 'datetime'}, 'yAxis': {'title': {'text':
        None}}, 'legend': {'enabled': True}, 'tooltip': {'shared': True},
        'plotOptions': {'area': {'lineWidth': 1, 'marker': {'lineWidth': 1}}}}


def invalid_arg(cond, msg):
    """ Return invalid argument response if *cond* evaluates to ``True``. """
    from gaetasks.views import apiret
    if cond:
        return apiret(40101, msg=msg)


@classmethod
def member_requests_change_policy_details(cls, val):
    """
        Create an instance of this class set to the
        ``member_requests_change_policy_details`` tag with value ``val``.

        :param MemberRequestsChangePolicyDetails val:
        :rtype: EventDetails
        """
    return cls('member_requests_change_policy_details', val)


def keyitem_add():
    """Add key map item

    """
    pass


def set_entry_direction(poly, outside_pt, ggr=None):
    """Check and set entry direction for a polygon.

    :param poly: A polygon.
    :param outside_pt: A point beyond the outside face of the polygon.
    :param ggr: EnergyPlus global geometry rules
    :return: A polygon with the vertices correctly oriented.

    """
    if not ggr:
        entry_direction = 'counterclockwise'
    else:
        entry_direction = ggr.Vertex_Entry_Direction.lower()
    if entry_direction == 'counterclockwise':
        if poly.is_clockwise(outside_pt):
            poly = poly.invert_orientation()
    elif entry_direction == 'clockwise':
        if not poly.is_clockwise(outside_pt):
            poly = poly.invert_orientation()
    return poly


def version_message(prog):
    """Program version message.

    Args:
        prog (State): program state.

    Returns:
        str: the message to print.
    """
    return '{} {}\n{}'.format(prog.name, prog.version, prog.copyright)


@classmethod
def get_value_from_choices(cls, value, choices):
    """ Returns the key for the choices tuple of tuples

        Note if you are using classes, they must implement the __in__ and __eq__ for the logical comparison.

        :param value: The raw value to test if it exists in the valid choices. Could be the key or the value in the dict
        :type value: Object
        :rtype: Object
        """
    if not choices:
        return None
    for key, val in choices:
        if value in (key, val):
            return key
    return None


def get_max_value_key(dictionary):
    """ Get the key of the maximum value in a dictionary.

    Parameters
    ----------
    dictionary: dict
        Dictionary to evaluate.

    Returns
    -------
    int
        Key of the maximum value.
    """
    if dictionary and isinstance(dictionary, dict):
        return max(dictionary, key=dictionary.get)
    else:
        return 0


def __iter__():
    """Return an iterator which provides the values from the source."""


def metar_to_iso8601(metardate):
    """Convert a metar date to an ISO8601 date."""
    if metardate is not None:
        date, hour = metardate.split()[:2]
        year, month, day = date.split('.')
        return '%s-%s-%s %s:%s:00Z' % (year, month, day, hour[:2], hour[2:4])


@classmethod
def get_default(cls, entity):
    """Get the default value for this attribute.

        :param entity: The entity this attribute is on
        :returns: The default value

        """
    return cls._default


def _az_string(az):
    """Return an azimuth angle as compass direction.

        >>> _az_string(0)
        'N'
        >>> _az_string(11)
        'N'
        >>> _az_string(12)
        'NNE'
        >>> _az_string(360 - 12)
        'NNW'
        >>> _az_string(360 - 11)
        'N'
    """
    assert 0.0 <= az <= 360
    compass = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW',
        'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW']
    assert len(compass) == 16
    step = 360 / len(compass)
    idx = int(round(az / step)) % len(compass)
    assert 0 <= idx < len(compass)
    return compass[idx]


def __ne__(A, other):
    """Returns true if both objects are not equal"""
    return not A == other


@classmethod
def NoAtmosCorr(cls):
    """Set 6S not to perform any atmospheric correction"""
    return '-1 No atm. corrections selected\n'


def _write_string(record, sub_string, pos):
    """Function that actually writes the generated strings to a 'stream"""
    new_pos = pos + len(sub_string)
    if pos > len(record):
        record = record.ljust(pos)
        out = record + sub_string
    elif pos == len(record):
        out = record + sub_string
    elif pos < len(record):
        out = record[:pos] + sub_string + record[new_pos:]
    return new_pos, out


def simplify(geoids):
    """
    Given a list of geoids, reduce it to a simpler set. If there are five or more geoids at one summary level
    convert them to a single geoid at the higher level.

    :param geoids:
    :return:
    """
    from collections import defaultdict
    aggregated = defaultdict(set)
    d = {}
    for g in geoids:
        if not bool(g):
            continue
        av = g.allval()
        d[av] = None
        aggregated[av].add(g)
    compiled = set()
    for k, v in aggregated.items():
        if len(v) >= 5:
            compiled.add(k)
            compiled.add(k.promote())
        else:
            compiled |= v
    return compiled


@classmethod
def black(cls, s):
    """Wrap text in black."""
    return cls._wrap_colour(s, cls.END)


def insert_bank_bins_option_group(parser):
    """ Add options to the optparser object for selecting templates in bins.

    Parameters
    -----------
    parser : object
        OptionParser instance.
    """
    bins_group = parser.add_argument_group(
        'Options for selecting templates in bins.')
    bins_group.add_argument('--bank-bins', nargs='+', default=None, help=
        "Ordered list of mass bin upper boundaries. An ordered list of type-boundary pairs, applied sequentially. Must provide a name (can be any unique string for tagging purposes), the parameter to bin on, and the membership condition via 'lt' / 'gt' operators. Ex. name1:component:lt2 name2:total:lt15"
        )
    bins_group.add_argument('--bank-file', default=None, help=
        'HDF format template bank file.')
    bins_group.add_argument('--f-lower', default=None, help=
        'Low frequency cutoff in Hz.')
    return bins_group


def div_with_small_value(n, d, eps=1e-08):
    """
    Small values are replaced by 1e-8 to prevent it from exploding.

    :param n: tensor
    :param d: tensor
    :return: n/d: tensor
    """
    d = d * (d > eps).float() + eps * (d <= eps).float()
    return n / d


def predictions(model, test_features):
    """
    Make some predictions foo the test data
    """
    return model.predict(test_features)


def normalize_str(main_string: str) ->str:
    """Replace a string with a list of substrings."""
    for elem in ['.', '-']:
        if elem in main_string:
            main_string = main_string.replace(elem, '_')
    return main_string


def release_dict(d, d_list, holdbacks):
    """Ensures that only new variables are returned"""
    response = dict()
    for i in d:
        if not i in d_list and not i in holdbacks:
            response[i] = d[i]
    return response


def shape_extent_to_header(shape, extent, nan_value=-9999):
    """ Create a header dict with shape and extent of an array
    """
    ncols = shape[1]
    nrows = shape[0]
    xllcorner = extent[0]
    yllcorner = extent[2]
    cellsize_x = (extent[1] - extent[0]) / ncols
    cellsize_y = (extent[3] - extent[2]) / nrows
    if cellsize_x != cellsize_y:
        raise ValueError('extent produces different cellsize in x and y')
    cellsize = cellsize_x
    header = {'ncols': ncols, 'nrows': nrows, 'xllcorner': xllcorner,
        'yllcorner': yllcorner, 'cellsize': cellsize, 'NODATA_value': nan_value
        }
    return header


@staticmethod
def join(*names, sep: str=None) ->str:
    """Used to create a name string. Can also be used to join paths by passing sep=os.path.sep

        :param names: the names to join
        :param sep: the join separator. Default to '.'
        :return: the names joined with the separator
        """
    _sep = sep if sep is not None else '.'
    return _sep.join(map(str, names))


def nla_get_flag(nla):
    """Return True if flag attribute is set.
    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/attr.c#L720

    Positional arguments:
    nla -- flag Netlink attribute (nlattr class instance).

    Returns:
    True if flag is set, otherwise False.
    """
    return not not nla


def get_registry():
    """
    Return the Pyramid application registry associated to the current running
    application

    :returns: A Pyramid registry instance
    """
    from pyramid_celery import celery_app
    return celery_app.conf['PYRAMID_REGISTRY']


def p_lp_expr_rp(p):
    """ bexpr : LP expr RP %prec ID
    """
    p[0] = p[2]


def close(i, j, tolerance):
    """
    check two float values are within a bound of one another
    """
    return i <= j + tolerance and i >= j - tolerance


@staticmethod
def createComposedResult(functionId, result):
    """
            Create a composed result from a function id and result id.
        """
    return result.getNativeValue() << 16 | int(functionId)


def load_file(cls, nc_filename):
    """ Sets cls.nc for a given nc_filename """
    if nc_filename in cls.nc_files:
        cls.nc = cls.nc_files[nc_filename]
    else:
        cls.nc = cls.get_nc(cls.filename_to_url(nc_filename))


@staticmethod
def plot_line(x0, y0, x1, y1):
    """Zingl-Bresenham line draw algorithm"""
    x0 = int(x0)
    y0 = int(y0)
    x1 = int(x1)
    y1 = int(y1)
    dx = abs(x1 - x0)
    dy = -abs(y1 - y0)
    if x0 < x1:
        sx = 1
    else:
        sx = -1
    if y0 < y1:
        sy = 1
    else:
        sy = -1
    err = dx + dy
    while True:
        yield x0, y0
        if x0 == x1 and y0 == y1:
            break
        e2 = 2 * err
        if e2 >= dy:
            err += dy
            x0 += sx
        if e2 <= dx:
            err += dx
            y0 += sy


def next_power_of_two(n):
    """
    Return next power of 2 greater than or equal to n
    """
    n -= 1
    shift = 1
    while n + 1 & n:
        n |= n >> shift
        shift *= 2
    return n + 1


def optimized_binary_search(tab, logsize):
    """Binary search in a table using bit operations

    :param tab: boolean monotone table
       of size :math:`2^\\textrm{logsize}`
       with tab[hi] = True
    :param int logsize:
    :returns: first i such that tab[i]
    :complexity: O(logsize)
    """
    hi = (1 << logsize) - 1
    intervalsize = 1 << logsize >> 1
    while intervalsize > 0:
        if tab[hi ^ intervalsize]:
            hi ^= intervalsize
        intervalsize >>= 1
    return hi


def add_position(p, name, pos):
    """Add a position to a portfolio.

    Parameters
    ----------
    p : alphapy.Portfolio
        Portfolio that will hold the position.
    name : int
        Unique identifier for the position, e.g., a stock symbol.
    pos : alphapy.Position
        New position to add to the portfolio.

    Returns
    -------
    p : alphapy.Portfolio
        Portfolio with the new position.

    """
    if name not in p.positions:
        p.positions[name] = pos
    return p


def mi(name):
    """ grab an object from the mids module. """
    import mids
    return getattr(mids, name, None)


def classify_key(item):
    """Sort key for item of (author, count) from classify_delta."""
    return -item[1], item[0]


def complement(input_number):
    """
    Calculate complement of input number.

    :param input_number: input number
    :type input_number: float
    :return: complement as float
    """
    try:
        return 1 - input_number
    except Exception:
        return 'None'


def nl_cb_get(cb):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/handlers.c#L244"""
    return cb


@classmethod
def for_element(cls, element):
    """ Returns an existing class or creates one for the given element.
        Returns a tuple with the class and a bool indicating creation.
        """
    assert element.represents_class
    class_name = element.name_if_class()
    if class_name in cls.known:
        return cls.known[class_name], False
    klass = cls(element)
    cls.known[class_name] = klass
    return klass, True


@classmethod
def is_request(cls, payload):
    """Returns True if the payload (which has a method) is a request.
        False means it is a notification."""
    return payload.get('id') is not None


@classmethod
def sf_invite_group(cls, val):
    """
        Create an instance of this class set to the ``sf_invite_group`` tag with
        value ``val``.

        :param SfInviteGroupType val:
        :rtype: EventType
        """
    return cls('sf_invite_group', val)


def IPStringtoInt(ip):
    """
    Converts a number from a dotted decimal string into a single unsigned int.
    Args:
        ip: dotted decimal ip address, like 12.34.56.78

    Returns: The IP address as a simple 32-bit unsigned integer

    """
    address_mask = ip.split('/')
    parts = address_mask[0].split('.')
    ip_int = 0
    for i in range(4):
        ip_int <<= 8
        if len(parts) > i:
            try:
                ip_int += int(parts[i])
            except:
                pass
    return ip_int


def _straceback():
    """Returns a string with the traceback."""
    import traceback
    return traceback.format_exc()


def chunkify(rg, n_max=1000):
    """
    generates sublists of at most n_max
    elements from the provided array
    :param rg: list
    :param n_max: the maximum sublist length
    :return:
    """
    m, n_len = 0, len(rg)
    while m < n_len:
        l, m = m, m + n_max
        yield rg[l:m]


def object_add_grid_scale_apply_operator(operator, context):
    """Scale an operators distance values by the grid size.

    """
    pass


def transform_record_data(data):
    """Return transformed data
        """


def get_text(xml, tag):
    """Return the text from a given tag and XML element.
    """
    elem = xml.find(tag)
    if elem is not None:
        return elem.text.strip()


def soft_delete_aware_query(context, *args, **kwargs):
    """Stack query helper that accounts for context's `show_deleted` field.

    :param show_deleted: if True, overrides context's show_deleted field.
    """
    query = context.session.query(*args)
    show_deleted = kwargs.get('show_deleted') or context.show_deleted
    if not show_deleted:
        query = query.filter_by(deleted_at=None)
    return query


@staticmethod
def positional_to_model(value):
    """Converts a positional argument to a model value"""
    return value


def _norm_text_angle(a):
    """Return the given angle normalized to -90 < *a* <= 90 degrees."""
    a = (a + 180) % 180
    if a > 90:
        a = a - 180
    return a


def GetBraviasNum(center, system):
    """Determine the Bravais lattice number, as used in GenHBravais

    :param center: one of: 'P', 'C', 'I', 'F', 'R' (see SGLatt from GSASIIspc.SpcGroup)
    :param system: one of 'cubic', 'hexagonal', 'tetragonal', 'orthorhombic', 'trigonal' (for R)
      'monoclinic', 'triclinic' (see SGSys from GSASIIspc.SpcGroup)
    :return: a number between 0 and 13
      or throws a ValueError exception if the combination of center, system is not found (i.e. non-standard)

    """
    if center.upper() == 'F' and system.lower() == 'cubic':
        return 0
    elif center.upper() == 'I' and system.lower() == 'cubic':
        return 1
    elif center.upper() == 'P' and system.lower() == 'cubic':
        return 2
    elif center.upper() == 'R' and system.lower() == 'trigonal':
        return 3
    elif center.upper() == 'P' and system.lower() == 'hexagonal':
        return 4
    elif center.upper() == 'I' and system.lower() == 'tetragonal':
        return 5
    elif center.upper() == 'P' and system.lower() == 'tetragonal':
        return 6
    elif center.upper() == 'F' and system.lower() == 'orthorhombic':
        return 7
    elif center.upper() == 'I' and system.lower() == 'orthorhombic':
        return 8
    elif center.upper() == 'A' and system.lower() == 'orthorhombic':
        return 9
    elif center.upper() == 'B' and system.lower() == 'orthorhombic':
        return 10
    elif center.upper() == 'C' and system.lower() == 'orthorhombic':
        return 11
    elif center.upper() == 'P' and system.lower() == 'orthorhombic':
        return 12
    elif center.upper() == 'C' and system.lower() == 'monoclinic':
        return 13
    elif center.upper() == 'P' and system.lower() == 'monoclinic':
        return 14
    elif center.upper() == 'P' and system.lower() == 'triclinic':
        return 15
    raise ValueError('non-standard Bravais lattice center=%s, cell=%s' % (
        center, system))


@classmethod
def from_str(cls, version_str: str):
    """
        Alternate constructor that accepts a string SemVer.
        """
    o = cls()
    o.version = version_str
    return o


def group_consecutives(vals, step=1):
    """Return list of consecutive lists of numbers from vals (number list)."""
    run = []
    result = [run]
    expect = None
    for v in vals:
        if v == expect or expect is None:
            run.append(v)
        else:
            run = [v]
            result.append(run)
        expect = v + step
    return result


@classmethod
def local_import_path(cls, source_root, address):
    """Returns the Go import path for the given address housed under the given source root.

        :param string source_root: The path of the source root the address is found within.
        :param address: The target address of a GoLocalSource target.
        :type: :class:`pants.build_graph.address.Address`
        :raises: `ValueError` if the address does not reside within the source root.
        """
    return cls.package_path(source_root, address.spec_path)


def _url_info(name):
    """
    Compose the URL for a json-file with information about the datasets.

    :param name: Name of the information e.g. 'datasets' or 'columns'.
    :return: String with the full URL.
    """
    url = 'https://simfin.com/api/bulk_info/{0}.php'
    url = url.format(name)
    return url


def spin(center: float=(0.0, 0.0, 0.0), axis: float=(0.0, 0.0, 0.0)):
    """Extrude selected boundary row around pivot point and current view axis

    :param center: Center, Center in global view space
    :type center: float
    :param axis: Axis, Axis in global view space
    :type axis: float
    """
    pass


def context_set_id(data_path: str='', value: str=''):
    """Set a context value to an ID data-block

    :param data_path: Context Attributes, RNA context string
    :type data_path: str
    :param value: Value, Assign value
    :type value: str
    """
    pass


def process_dat(filepath):
    """
    Process RNAz dat file format (generated by rnazCluster.pl

    :param filepath:
    :return:
    """
    sizes = []
    with open(filepath, 'r') as fh:
        for line in fh:
            if line.startswith('locus'):
                x = line.split()
                start = int(x[2])
                end = int(x[3])
                length = end - start
                sizes.append(length)
    return sizes


def lightcurveChopList(parentData, axis, timeInterval):
    """
    Breaks observation data into observations separated by timeInterval. Returns list of times

    :param parentData: Glue (Pandas) Data Object containing CSV lightcurve data
    :type parentData: glue.core.data.Data

    :param axis: parameter to split across (usual = time)
    :type axis: string

    :param timeInterval: interval/amount to split parameter 'axis' across
    :type timeInterval: numpy.float64

    :returns: list -- List of autochop regions
    """
    import numpy
    timeDifferences = numpy.diff(parentData[axis])
    obsWindows = []
    obsStart = parentData[axis, 0]
    for index, difference in enumerate(timeDifferences):
        if difference > timeInterval:
            obsEnd = parentData['MeanTime', index]
            obsWindows.append((index, obsStart, obsEnd))
            obsStart = parentData['MeanTime', index + 1]
    obsWindows.append((len(parentData[axis]), obsStart, parentData[
        'MeanTime', -1]))
    return obsWindows


def render_git_describe_long(pieces):
    """TAG-DISTANCE-gHEX[-dirty].

    Like 'git describe --tags --dirty --always -long'.
    The distance/hash is unconditional.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


def get_counter():
    """Each upload status gets a unique number: this method returns that
        number. This provides a handle to this particular upload, so a web
        page can generate a suitable hyperlink."""


@staticmethod
def to_genotype(phenotype):
    """
        Converts environment representation of a state to LCS
        representation.
        """
    phenotype = str(phenotype),
    return phenotype


def get_weights(G):
    """
    Given a graph G, returns a list of weights. If the graph is unweighted,
    returns a list of 1s the same length as the number of edges.
    """
    try:
        weights = G.es['weight']
    except KeyError:
        weights = [(1) for e in G.es]
    return weights


def FinalSpin(Xi, eta):
    """Computes the spin of the final BH that gets formed after merger. This is done usingn Eq 5-6 of arXiv:0710.3345"""
    s4 = -0.129
    s5 = -0.384
    t0 = -2.686
    t2 = -3.454
    t3 = 2.353
    etaXi = eta * Xi
    eta2 = eta * eta
    finspin = (Xi + s4 * Xi * etaXi + s5 * etaXi * eta + t0 * etaXi + 2.0 *
        3.0 ** 0.5 * eta + t2 * eta2 + t3 * eta2 * eta)
    if finspin > 1.0:
        raise ValueError('Value of final spin > 1.0. Aborting')
    else:
        return finspin


def forYear(year):
    """(classmethod) Returns an interval of months for the given year."""


def if_no_repeat(event):
    """ Callable that returns True when the previous event was delivered to
    another handler. """
    return not event.is_repeat


def point_distance(point_1: tuple, point_2: tuple) ->float:
    """
    Calculate the distance from point_1 to point_2.
    """
    return ((point_1[0] - point_2[0]) ** 2 + (point_1[1] - point_2[1]) ** 2
        ) ** 0.5


def getChild(name):
    """
        Return the :class:`IPath` for child with `name`.

        Raise ChildNotFound if child does not exists.
        """


def remove_output(nb):
    """Remove all outputs."""
    for cell in nb['cells']:
        if 'outputs' in cell:
            cell['outputs'] = []


def python_format(a, prec, align=''):
    """Format an array into standard form and return as a string.

    args:
        a: the array
        prec: the precision to output the array to
        align: anything that can go before the . in python formatting
    """
    format_ = (f' {{:{align}.{prec}E}}' * a.shape[1] + '\n') * a.shape[0]
    return format_.format(*a.flatten())


def tab_to_xlsx(sbtab_object):
    """
    Converts SBtab object to xlsx file object.

    Parameters
    ----------
    sbtab_object: SBtab.SBtabTable
        SBtab table object.

    Returns: xlsx file object
        SBtab table as xlsx file object.
    """
    import openpyxl
    wb = openpyxl.Workbook()
    ws = wb.active
    ws['A1'] = sbtab_object.header_row
    ws.append(sbtab_object.columns)
    for row in sbtab_object.value_rows:
        ws.append(row)
    wb.save('transition.xlsx')
    f = open('transition.xlsx', 'rb')
    fileobject = f.read()
    f.close()
    return fileobject


def plus_or_dot(pieces):
    """Return a + if we don't already have one, else return a ."""
    if '+' in pieces.get('closest-tag', ''):
        return '.'
    return '+'


@classmethod
def to_json(cls, obj):
    """
        Serialize wrapped datetime.timedelta instance to a string the
        with the following format:
            [DAYS]d [SECONDS]s [MICROSECONDS]us
        """
    return '{0}d {1}s {2}us'.format(obj.days, obj.seconds, obj.microseconds)


def parse_string(text):
    """Parse a string to a string (removing single and double quotes)."""
    if len(text) >= 2 and text[0] in ('"', "'") and text[-1] in ('"', "'"):
        text = text[1:-1]
    return text.strip()


def getAAColours():
    """
    Generates a dictionary which assigns a colour to each amino acid.
    Based on the "RasmMol" amino colour scheme and the table here:
        http://acces.ens-lyon.fr/biotic/rastop/help/colour.htm
    (plus grey for "X" and white for "-")

    Parameters
    ----------
    None

    Returns
    -------
    dict
        Dictionary where keys are single letter amino acid codes and
        values are hexadecimal codes for colours
    """
    return {'D': '#E60A0A', 'E': '#E60A0A', 'C': '#E6E600', 'M': '#E6E600',
        'K': '#145AFF', 'R': '#145AFF', 'S': '#FA9600', 'T': '#FA9600', 'F':
        '#3232AA', 'Y': '#3232AA', 'N': '#00DCDC', 'Q': '#00DCDC', 'G':
        '#EBEBEB', 'L': '#0F820F', 'V': '#0F820F', 'I': '#0F820F', 'A':
        '#C8C8C8', 'W': '#B45AB4', 'H': '#8282D2', 'P': '#DC9682', 'X':
        '#b2b2b2', '-': '#FFFFFF00'}


@classmethod
def fromdata(cls, data, bps=2):
    """Encode data as payload, using a given number of bits per sample.

        It is assumed that the last dimension is the number of channels.
        """
    if data.dtype.kind == 'c':
        raise ValueError('Mark5B format does not support complex data.')
    encoder = cls._encoders[bps]
    words = encoder(data).view(cls._dtype_word)
    return cls(words, nchan=data.shape[-1], bps=bps)


def AddComment(*args, **kwargs):
    """ Stub Anduin function."""
    print('AddComment', args, kwargs)


@classmethod
def a_or_an(cls, word):
    """
        Heuristically attaches either "a" or "an" to a given English noun.
        a_or_an("gene") => "a gene"
        a_or_an("accession") => "an accession"
        """
    article = cls.select_a_or_an(word)
    return '%s %s' % (article, word)


def __call__():
    """Returns information of order."""


def moving_average(array, N=3):
    """compute the moving average for a list/array. N is the number
    of elements averaged over, it always uses the quiered element as the central
    point and hence must be an odd number"""
    if not isinstance(N, int) or N % 2 == 0:
        raise Exception('N must be an odd integer')
    idx = round(N / 2) - 1
    length = len(array)
    out = [0] * length
    for i in range(len(array)):
        if i < idx:
            a = 0
            b = i + idx + 1
        elif length - i < idx:
            a = i - idx
            b = len(array) - 1
        else:
            a = i - idx
            b = i + idx + 1
        out[i] = sum(array[a:b]) / len(array[a:b])
    return out


def obtener_total_votos(df):
    """
    A partir del dataframe de actas, extrae la columna de votos totales y
    la retorna como una lista
    :param df: Dataframe resultado de leer actas.csv
    :return: Lista de python con los votos totales
    """
    df_total_votos = df['VOTOS RECIBIDOS']
    return df_total_votos.values.tolist()


def glRotate(angle, x, y, z):
    """Multiply the current matrix by a rotation matrix

    :param angle: Specifies the angle of rotation in degrees.
    :param z: Specify the x, y, and z coordinates of a vector respectively.
    """
    pass


def decode_source(source_bytes):
    """Decode bytes representing source code and return the string.
    Universal newline support is used in the decoding.
    """
    import _io
    import tokenize
    source_bytes_readline = _io.BytesIO(source_bytes).readline
    encoding = tokenize.detect_encoding(source_bytes_readline)
    newline_decoder = _io.IncrementalNewlineDecoder(None, True)
    return newline_decoder.decode(source_bytes.decode(encoding[0]))


def chunks(l, n):
    """ split list into n chunks

        will return empty lists if n > len(l)

        :param l: list of values you wish to split
        :type l: list
        :param n: number of sub lists you want to generate
        :type n: int

        :returns sub_lists: list of lists
        :rtype sub_lists: list
    """
    sub_lists = [[] for _ in range(n)]
    for num, i in enumerate(l):
        sub_lists[num % n].append(i)
    return sub_lists


def _warn_keyword_parameter(func_name, kwargs):
    """
    Backwards-compatibility with Python 2.7 to allow treating 'warn' as keyword-only.
    """
    if not kwargs:
        return False
    elif len(kwargs) > 1 or 'warn' not in kwargs:
        kwargs.pop('warn', None)
        arg = next(iter(kwargs.keys()))
        raise TypeError('{}() got an unexpected keyword argument {!r}'.
            format(func_name, arg))
    return kwargs['warn']


def importCode(code, name, add_to_sys_modules=0):
    """
    Import dynamically generated code as a module. code is the
    object containing the code (a string, a file handle or an
    actual compiled code object, same types as accepted by an
    exec statement). The name is the name to give to the module,
    and the final argument says wheter to add it to sys.modules
    or not. If it is added, a subsequent import statement using
    name will return this module. If it is not added to sys.modules
    import will try to load it in the normal fashion.

    import foo

    is equivalent to

    foofile = open("/path/to/foo.py")
    foo = importCode(foofile,"foo",1)

    Returns a newly generated module.
    """
    import sys
    import imp
    module = imp.new_module(name)
    exec(code)
    if add_to_sys_modules:
        sys.modules[name] = module
    return module


def floatimg2uint8(image):
    """
    Convert array with floats to 'uint8' and rescale from [0,1] to [0, 256].

    Converts only if image.dtype != uint8.

    >>> import numpy as np
    >>> image = np.eye(10, 20, dtype=float)
    >>> arr = floatimg2uint8(image)
    >>> np.max(arr)
    255

    :param numpy.array image: Numpy array with range [0,1]
    :return: Numpy array with range [0,255] and dtype 'uint8'
    :rtype: numpy array
    """
    return (image * 255).astype('uint8') if image.dtype != 'uint8' else image


def order_update_request(message, futures):
    """Intercepts order update request info messages (ou-req) and check for
    Future objets with a matching cid.

    Parameters
    ----------
    message : str
        The unaltered response message returned by bitfinex.
    futures : dict
        A dict of intercept_id's and future objects.
        dict{intercept_id, future_object}
    """
    order_id = message[4][0]
    future_id = f'ou-req_{order_id}'
    futures[future_id].set_result({'status': message[6], 'id': message[4][0
        ], 'cid': message[4][2], 'response': message[4], 'comment': message[7]}
        )
    del futures[future_id]


def plus_or_dot(pieces):
    """Return a + if we don't already have one, else return a ."""
    if '+' in pieces.get('closest-tag', ''):
        return '.'
    return '+'


@classmethod
def legal_holds_remove_members(cls, val):
    """
        Create an instance of this class set to the
        ``legal_holds_remove_members`` tag with value ``val``.

        :param LegalHoldsRemoveMembersType val:
        :rtype: EventType
        """
    return cls('legal_holds_remove_members', val)


def sfloat(S):
    """convert a string to a float, treating an all-blank string as zero"""
    if S.strip():
        return float(S)
    else:
        return 0.0


def sync(args):
    """Save Aegea configuration to your AWS IAM account, or retrieve a previously saved configuration"""
    raise NotImplementedError()


@classmethod
def get_object_info(cls, where_clause=None):
    """Get model and field information about the model class."""
    related_model_info = {}
    for fkf in cls._meta.refs:
        rel_mod = fkf.rel_model
        if rel_mod.__class__.__name__ != cls.__name__:
            table = rel_mod._meta.table_name
            pkey = rel_mod._meta.primary_key.name
            related_model_info[fkf.name] = {'db_column': fkf.column_name,
                'db_table': table, 'primary_key': pkey}
    where_clause = where_clause if where_clause else {}
    field_types = {}
    for field_name, field in cls._meta.fields.items():
        field_types[field_name] = str(field.field_type)
    js_object = {'callable_name': cls.__module__.split('.').pop().lower(),
        'last_changed_date': cls.last_change_date(), 'primary_keys': cls.
        get_primary_keys(), 'field_list': cls._meta.sorted_field_names,
        'field_types': field_types, 'foreign_keys': cls.cls_foreignkeys(),
        'related_models': related_model_info, 'related_names': cls.
        cls_revforeignkeys(), 'record_count': cls.select().where(cls.
        where_clause(where_clause)).count()}
    return js_object


def merge_sql(table_left, table_right, condition='', how='inner'):
    """
    Merge two datasets using database join.
    The table_left is joined with table_right using the method `how` (inner, left inner/outer, right inner/outer).
    The parameter `condition` is appended to the query, specify the join keys (example using ("index")).

    Parameters
    ----------
    table_left :
        left input table to join
    table_right :
        right input table to join
    condition :
        join condition, example "using (index)"
    how :
        join type inner, left, right

    Returns
    -------
    str
        query the generated query

    Note
    ----

    """
    query = (
        'select * from {table_left} left_table {how} join {table_right} right_table {condition};'
        .format(table_left=table_left, table_right=table_right, condition=
        condition, how=how))
    return query


@staticmethod
def get_video_frames(master_file):
    """Get sorted list of video frames."""
    return sorted(master_file.get('frame', []), key=lambda s: float(s[
        'tags']['timestamp']))


def return_union_close():
    """union of statements, close statement"""
    return '            return __result'


def reduction_collapses(inout, axis, verbose=0):
    """
    This collapse dimensions that are not needed when computing
    reduction.  This is usefull as it lower the indexing computation
    that is heavier on gpu then on cpu.

    This is a generic version. It collapse dimensions at any place in
    the shape.
    @param: inout: tuple(input, output)
    @param: axis: None, interger, list of 1 interger
                  The axis over witch we will do reduction.
    @return: (ndims, (input dims, input strides, input pattern), out strides)
             after collapsing.

    :note: we suppose that we can always collapse the output dimensions.
    """
    input = inout[0]
    out = inout[1]
    if axis is None:
        if input.flags['C_CONTIGUOUS'] or input.flags['F_CONTIGUOUS']:
            return 0, ((input.size,), (input.itemsize,), axis), (0,)
    if input.ndim == 1:
        assert axis == [0] or axis == 0 or axis is None
        return 1, (input.shape, input.strides, axis), (0,)
    if not isinstance(axis, (list, tuple)):
        local_axis = [axis]
    else:
        local_axis = list(axis)
    assert axis is None or len(local_axis) == 1
    local_dims = list(input.shape)
    local_str = list(input.strides)
    out_strides = list(out.strides)
    nd_orig = len(local_dims)
    collapsable = [1] * nd_orig
    nd_collapse = nd_orig
    if verbose > 2:
        print('before broadcast collapse')
        print(' nd_collapse', nd_collapse)
        print(' local_dims', local_dims)
        print(' local_str inputs', local_str)
        print(' local_axis', local_axis)
    for id in range(nd_collapse):
        if local_dims[id] == 1:
            for j in range(id + 1, nd_collapse):
                local_dims[j - 1] = local_dims[j]
                local_str[j - 1] = local_str[j]
                if axis is not None:
                    out_strides[j - 2] = out_strides[j - 1]
            if id in local_axis:
                local_axis.remove(id)
            for axis_pos in range(len(local_axis)):
                if local_axis[axis_pos] > id:
                    local_axis[axis_pos] -= 1
            nd_collapse -= 1
            id -= 1
    if verbose > 2:
        print('after broadcast collapse')
        print(' nd_collapse', nd_collapse)
        print(' local_dims', local_dims)
        print(' local_str inputs', local_str)
        print(' local_axis', local_axis)
        print(' out_strides', out_strides)
    nd_collapse_ = [1] * nd_orig
    for i in range(nd_collapse - 1, 0, -1):
        if local_str[i] * local_dims[i] != local_str[i - 1]:
            nd_collapse_[i] = 0
        elif (i in local_axis) != (i - 1 in local_axis):
            nd_collapse_[i] = 0
    if verbose > 1:
        print('nd_collapse_', nd_collapse_)
    nd_collapse2 = nd_collapse
    for i in range(nd_collapse - 1, 0, -1):
        if nd_collapse_[i] == 1:
            local_dims[i - 1] *= local_dims[i]
            local_str[i - 1] = local_str[i]
            for j in range(i + 1, nd_collapse):
                local_dims[j - 1] = local_dims[j]
                local_str[j - 1] = local_str[j]
                if axis is not None:
                    out_strides[j - 2] = out_strides[j - 1]
            if i in local_axis:
                local_axis.remove(i)
            for axis_pos in range(len(local_axis)):
                if local_axis[axis_pos] > i:
                    local_axis[axis_pos] -= 1
            nd_collapse2 -= 1
    nd_collapse = nd_collapse2
    if nd_collapse == 1:
        if local_str[nd_collapse - 1] == input.itemsize:
            nd_collapse = 0
    if verbose:
        print('end collapsing')
        print(' nd_collapse', nd_collapse)
    if verbose > 1:
        print(' local_dims', local_dims)
        print(' local_str inputs', local_str)
        print(' local_axis', local_axis)
        print(' out_strides', out_strides)
    local_dims = local_dims[:nd_collapse]
    local_str = local_str[:nd_collapse]
    out_strides = out_strides[:nd_collapse]
    return nd_collapse, (local_dims, local_str, local_axis), out_strides


def capacity_miss_LRU(csdp, cache_size):
    """
    Capacity miss rate using an LRU cache.
    """
    return 1.0 - csdp.get(int(cache_size + 0.5))


def clear_line():
    """Clear the line and store in history

    """
    pass


@classmethod
def _convert_material_parameters(cls, mat_props):
    """Handle exceptions for converting input material dict in Standard Form.

        Returns
        -------
        dict
            Material properties converted to Standard Form.

        Raises
        ------
        TypeError
            If mat_props is neither in Quick or Standard Form, but requires to
            be written as a nested dict.

        """
    try:
        if mat_props is None:
            dict_prop = {}
        elif isinstance(mat_props, dict):
            mat_props['Modulus'].keys()
            dict_prop = mat_props
        else:
            raise TypeError(
                'Nested dict of material parameters required.  See Tutorial.')
    except KeyError:
        print('Converting mat_props to Standard Form.')
        dict_prop = cls._to_standard_dict(mat_props)
    return dict_prop


def int_to_decimal_str(integer):
    """
    Helper to convert integers (representing cents) into decimal currency
    string. WARNING: DO NOT TRY TO DO THIS BY DIVISION, FLOATING POINT
    ERRORS ARE NO FUN IN FINANCIAL SYSTEMS.
    @param integer The amount in cents
    @return string The amount in currency with full stop decimal separator
    """
    int_string = str(integer)
    if len(int_string) < 2:
        return '0.' + int_string.zfill(2)
    else:
        return int_string[:-2] + '.' + int_string[-2:]


def compute_chi_squared(data):
    """
    Calculate Chi-Squared value for a given byte array.

    Keyword arguments:
    data -- data bytes
    """
    if len(data) == 0:
        return 0
    expected = float(len(data)) / 256.0
    observed = [0] * 256
    for b in data:
        observed[b] += 1
    chi_squared = 0
    for o in observed:
        chi_squared += (o - expected) ** 2 / expected
    return chi_squared


def extract_sha256_hash(hash):
    """Extrach SHA256 hash or return None
    """
    prefix = 'sha256:'
    if hash and hash.startswith(prefix):
        return hash.replace(prefix, '')
    return None


def successors_query(var_name, node_id, node_label, edge_label,
    successor_label=None, undirected=False):
    """Generate query for getting the ids of all the successors of a node.

    Parameters
    ----------
    var_name
        Name of the variable corresponding to the node to match
    node_id
        Id of the node to match
    node_label : optional
        Label of the node to match, default is 'node'
    edge_label : optional
        Label of the edge to match, default is 'edge'
    successor_label : optional
        Label of the successors we want to find,
        'node_label' is used if None.
    """
    if successor_label is None:
        successor_label = node_label
    if undirected is False:
        arrow = '>'
    else:
        arrow = ''
    query = "OPTIONAL MATCH (n{}:{} {{id : '{}'}})-[:{}]-{} (suc:{})\n".format(
        var_name, node_label, node_id, edge_label, arrow, successor_label
        ) + 'RETURN suc.id as suc'
    return query


def get_is_head_of_word(naive_tokens, sequence_tokens):
    """
    Return a list of flags whether the token is head(prefix) of naively split tokens

    ex) naive_tokens: ["hello.", "how", "are", "you?"]
        sequence_tokens: ["hello", ".", "how", "are", "you", "?"]

        => [1, 0, 1, 1, 1, 0]

    * Args:
        naive_tokens: a list of tokens, naively split by whitespace
        sequence_tokens: a list of tokens, split by 'word_tokenizer'

    * Returns:
        is_head_of_word: a list with its length the same as that of 'sequence_tokens'.
            has 1 if the tokenized word at the position is head(prefix) of a `naive_token`
            and 0 if otherwise.
    """
    is_head_of_word = []
    for naive_token in naive_tokens:
        consumed_chars = 0
        consumed_words = 0
        for sequence_token in sequence_tokens:
            if naive_token[consumed_chars:].startswith(sequence_token):
                is_head_of_word.append(0 if consumed_chars else 1)
                consumed_chars += len(sequence_token)
                consumed_words += 1
            else:
                break
        sequence_tokens = sequence_tokens[consumed_words:]
    return is_head_of_word


@classmethod
def with_setup(cls, *setup_phases):
    """Create PhaseGroup creator function with predefined setup phases."""
    return cls.with_context(setup_phases, [])


def bias_score(contingency, yes_category=2):
    """
        Returns the bias score given dichotomous contingency data
        Author: Dougie Squire
        Date: 12/05/2018

        Parameters
        ----------
        contingency : xarray DataArray
            A 2 category contingency table of the form output from doppyo.skill.contingency
        yes_category : value, optional
            The coordinate value of the category corresponding to 'yes'

        Returns
        -------
        bias_score : xarray DataArray
            An array containing the bias scores

        Examples
        --------
        >>> da_cmp = xr.DataArray(np.random.normal(size=(3,3)),
        ...                       coords=[('x', np.arange(3)), ('y', np.arange(3))])
        >>> da_ref = xr.DataArray(np.random.normal(size=(3,3)),
        ...                       coords=[('x', np.arange(3)), ('y', np.arange(3))])
        >>> category_edges_cmp = np.linspace(-2,2,3)
        >>> category_edges_ref = np.linspace(-2,2,3)
        >>> contingency = doppyo.skill.contingency(da_cmp, da_ref, category_edges_cmp,
        ...                                        category_edges_ref, over_dims='y')
        >>> doppyo.skill.bias_score(contingency)
        <xarray.DataArray 'bias_score' (x: 3)>
        array([0.5     , 0.333333, 1.      ])
        Coordinates:
          * x        (x) int64 0 1 2

        Notes
        -----
        See http://www.cawcr.gov.au/projects/verification/
    """
    no_category = abs(yes_category - 2) + 1
    if len(contingency.comparison_category) > 2:
        raise ValueError(
            'Bias score is defined for dichotomous contingency data only')
    hits = contingency.sel(comparison_category=yes_category,
        reference_category=yes_category, drop=True)
    false_alarms = contingency.sel(comparison_category=yes_category,
        reference_category=no_category, drop=True)
    misses = contingency.sel(comparison_category=no_category,
        reference_category=yes_category, drop=True)
    return ((hits + false_alarms) / (hits + misses)).rename('bias_score')


@classmethod
def default_runatweekday(cls):
    """ default: runatweekday
        """
    return False


def render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

    Like 'git describe --tags --dirty --always'.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


@classmethod
def __in_dev_mode__(cls) ->bool:
    """Return the actual dev-mode.

        Returns
        -------
        bool
            The value of the actual dev-mode.

        Examples
        --------
        >>> from mixt import set_dev_mode, unset_dev_mode, in_dev_mode
        >>> in_dev_mode()
        True
        >>> unset_dev_mode()
        >>> in_dev_mode()
        False
        >>> set_dev_mode()
        >>> in_dev_mode()
        True

        """
    return cls.__dev_mode__


def normalize_rating(v):
    """Normalize five star ratings between 0 to 1.

    Args:
      v: rating which is between 1 to 5

    Returns:
      Normalized rating data between 0 to 1
    """
    return (v - 1.0) / 4.0


def isoformat(dt):
    """Return iso-formatted timestamp

    Like .isoformat(), but uses Z for UTC instead of +00:00
    """
    return dt.isoformat().replace('+00:00', 'Z')


def shasum(*values: str) ->str:
    """Base-16-encode a string using SHA-256 truncated to 32 characters."""
    from hashlib import sha256
    return sha256(''.join(values).encode()).hexdigest()[:32]


def reverse_complement(seq):
    """Creates reverse complement of a DNA string."""
    seq = seq.upper()
    return seq.translate(str.maketrans('ATGCN', 'TACGN'))[::-1]


def _split_tree(layout):
    """Returns a tuple of two layouts, one containing the left
    subtree of the root vertex, and one containing the original tree
    with the left subtree removed."""
    one_found = False
    m = None
    for i in range(len(layout)):
        if layout[i] == 1:
            if one_found:
                m = i
                break
            else:
                one_found = True
    if m is None:
        m = len(layout)
    left = [(layout[i] - 1) for i in range(1, m)]
    rest = [0] + [layout[i] for i in range(m, len(layout))]
    return left, rest


def list_web_acls(NextMarker=None, Limit=None):
    """
    Returns an array of  WebACLSummary objects in the response.
    See also: AWS API Documentation

    Examples
    The following example returns an array of up to 100 web ACLs.
    Expected Output:

    :example: response = client.list_web_acls(
        NextMarker='string',
        Limit=123
    )

    :type NextMarker: string
    :param NextMarker: If you specify a value for Limit and you have more WebACL objects than the number that you specify for Limit , AWS WAF returns a NextMarker value in the response that allows you to list another group of WebACL objects. For the second and subsequent ListWebACLs requests, specify the value of NextMarker from the previous response to get information about another batch of WebACL objects.

    :type Limit: integer
    :param Limit: Specifies the number of WebACL objects that you want AWS WAF to return for this request. If you have more WebACL objects than the number that you specify for Limit , the response includes a NextMarker value that you can use to get another batch of WebACL objects.

    :rtype: dict
    :return: {
        'NextMarker': 'string',
        'WebACLs': [
            {
                'WebACLId': 'string',
                'Name': 'string'
            },
        ]
    }

    """
    pass


def sigma_Flynn(Vc):
    """Calculates Lennard-Jones molecular diameter.
    Uses critical volume. CSP method by [1]_ as reported in [2]_.

    .. math::
        \\sigma = 0.561(V_c^{1/3})^{5/4}

    Parameters
    ----------
    Vc : float
        Critical volume of fluid [m^3/mol]

    Returns
    -------
    sigma : float
        Lennard-Jones molecular diameter, [Angstrom]

    Notes
    -----
    Vc is originally in units of mL/mol.

    Examples
    --------
    >>> sigma_Flynn(0.000268)
    5.2506948422196285

    References
    ----------
    .. [1] Flynn, L.W., M.S. thesis, Northwestern Univ., Evanston, Ill. (1960).
    .. [2] Stiel, L. I., and George Thodos. "Lennard-Jones Force Constants
       Predicted from Critical Properties." Journal of Chemical & Engineering
       Data 7, no. 2 (April 1, 1962): 234-36. doi:10.1021/je60013a023
    """
    Vc = Vc * 1000000.0
    sigma = 0.561 * (Vc ** (1 / 3.0)) ** 1.2
    return sigma


def string_to_tuple(version):
    """Convert version as string to tuple

    Example:
        >>> string_to_tuple("1.0.0")
        (1, 0, 0)
        >>> string_to_tuple("2.5")
        (2, 5)

    """
    return tuple(map(int, version.split('.')))


@staticmethod
def normalizeElem(elem):
    """Return the decomposition of elem (list of items)."""
    return [(elem, 1)]


def _validate_kwargs(input_dict, compare_dict):
    """
    Function to deal with keyword arguments.

    :param input_dict: matplotlib kwargs dictionary with custom arguments
    :type input_dict: :class: `dict`
    :param compare_dict: matplotlib kwargs of default to use arguments
    :type compare_dict: :class: `dict`
    """
    for key, val in compare_dict.items():
        if input_dict is None:
            input_dict = compare_dict.copy()
        elif key not in input_dict:
            input_dict[key] = val
    return input_dict


def _compute_n_j_plus_one(one_over_delta_grid,
    one_over_delta_grid_bar_forward, C_forward, B_forward, one_minus_delta_j):
    """
    equation for the CC n_j +1 term

    :param one_over_delta_grid: the total change in energy
    :param one_over_delta_grid_bar_backward: the backward change in energy for the second derivative
    :param C_forward: the forward dispersion term
    :param B_forward: the forward heating term
    :param one_minus_delta_j: 1 - delta_j
    """
    return one_over_delta_grid * (one_minus_delta_j * B_forward +
        one_over_delta_grid_bar_forward * C_forward)


def merge_as_sets(*args):
    """Create an order set (represented as a list) of the objects in
    the sequences passed as arguments."""
    s = {}
    for x in args:
        for y in x:
            s[y] = True
    return sorted(s)


def channel_unbalancedness_and_commit_fee(local_balance, capacity,
    commit_fee, initiator):
    """
    Calculates the unbalancedness.

    :param local_balance: int
    :param capacity: int
    :param commit_fee: int
    :param initiator: bool
    :return: float:
        in [-1.0, 1.0]
    """
    commit_fee = 0 if not initiator else commit_fee
    return -(2 * float(local_balance + commit_fee) / capacity - 1), commit_fee


def translate_attach(TRANSFORM_OT_translate=None, NODE_OT_attach=None,
    NODE_OT_insert_offset=None):
    """Move nodes and attach to frame

    :param TRANSFORM_OT_translate: Move, Move selected items
    :param NODE_OT_attach: Attach Nodes, Attach active node to a frame
    :param NODE_OT_insert_offset: Insert Offset, Automatically offset nodes on insertion
    """
    pass


@classmethod
def _find_entity_references(cls, code):
    """
        Find all entity references from instantiations or block configurations
        """
    references = []
    for match in cls._entity_reference_re.finditer(code):
        if match.group('arch') is None:
            references.append(cls('entity', match.group('lib'), match.group
                ('ent')))
        else:
            references.append(cls('entity', match.group('lib'), match.group
                ('ent'), match.group('arch')))
    return references


def handle_dbadmin_command(command, options, args):
    """Handle a dbadmin command

        :param command: the command string
        :param options: extra optparser options
        :param args: a list of C{args}
        """
    pass


def list_to_string(list_of_strings):
    """
    Function that takes a list of string and converts it to a string.
    For example: ["apple", "banana", "cherry"] is changed to "apple; banana; cherry"
    """
    string = ''
    if list_of_strings is not None:
        for item in list_of_strings:
            if len(string) > 0:
                string += '; '
            string += item
    return string


def skin_armature_create(modifier: str=''):
    """Create an armature that parallels the skin layout

    :param modifier: Modifier, Name of the modifier to edit
    :type modifier: str
    """
    pass


def assert_item(dct, key, expected_value):
    """Asserts that ``dct[key] == expected_value``"""
    actual_value = dct.pop(key, expected_value)
    if actual_value != expected_value:
        raise ValueError('bad value: {0} = {1}; should be {2}'.format(key,
            actual_value, expected_value))


def resetForUser(userid):
    """Remove answer for a single user"""


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


@staticmethod
def clean_characters(entry):
    """A helper function to convert special characters to LaTeX characters"""
    char_to_replace = {'&': '\\&', '#': '\\#', '–': '--', '—': '--', '∕':
        '/', 'κ': 'k', '×': 'x', '"': "'"}
    entry_key = ['publisher', 'publication', 'title']
    for k in entry_key:
        for char, repl_char in char_to_replace.items():
            entry[k] = entry[k].replace(char, repl_char)


def console_has_colours(stream):
    """
    Detects if the specified stream has colourising capability.

    :param stream: stream to check (typically sys.stdout)
    """
    if not hasattr(stream, 'isatty'):
        return False
    if not stream.isatty():
        return False
    try:
        import curses
        curses.setupterm()
        return curses.tigetnum('colors') > 2
    except:
        return False


def data_for_idx(face_idx, dem, grid, data):
    """get data for cell with face_idx face_idx"""
    face = grid['face_coordinates'][face_idx]
    affine = dem['affine']
    idx = (face - (affine.xoff, affine.yoff)) / (affine.a, affine.e)
    i_min, i_max = int(idx[:, (0)].min()), int(idx[:, (0)].max())
    j_min, j_max = int(idx[:, (1)].min()), int(idx[:, (1)].max())
    dem_i = dem['band'][j_min:j_max, i_min:i_max]
    vol_i = data['vol1'][face_idx]
    data = dict(face=face, dem=dem_i, vol=vol_i)
    return data


@classmethod
def AddArguments(cls, argument_group):
    """Adds command line arguments to an argument group.

    This function takes an argument parser or an argument group object and adds
    to it all the command line arguments this helper supports.

    Args:
      argument_group (argparse._ArgumentGroup|argparse.ArgumentParser):
          argparse group.
    """
    argument_group.add_argument('--parsers', dest='parsers', type=str,
        action='store', default='', metavar='PARSER_FILTER_EXPRESSION',
        help=
        'Define which presets, parsers and/or plugins to use, or show possible values. The expression is a comma separated string where each element is a preset, parser or plugin name. Each element can be prepended with an exclamation mark to exclude the item. Matching is case insensitive. Examples: "linux,!bash_history" enables the linux preset, without the bash_history parser. "sqlite,!sqlite/chrome_history" enables all sqlite plugins except for chrome_history". "win7,syslog" enables the win7 preset, as well as the syslog parser. Use "--parsers list" or "--info" to list available presets, parsers and plugins.'
        )


def create_resource_group(resourceGroupTags=None):
    """
    Creates a resource group using the specified set of tags (key and value pairs) that are used to select the EC2 instances to be included in an Amazon Inspector assessment target. The created resource group is then used to create an Amazon Inspector assessment target. For more information, see  CreateAssessmentTarget .
    See also: AWS API Documentation

    Examples
    Creates a resource group using the specified set of tags (key and value pairs) that are used to select the EC2 instances to be included in an Amazon Inspector assessment target. The created resource group is then used to create an Amazon Inspector assessment target.
    Expected Output:

    :example: response = client.create_resource_group(
        resourceGroupTags=[
            {
                'key': 'string',
                'value': 'string'
            },
        ]
    )

    :type resourceGroupTags: list
    :param resourceGroupTags: [REQUIRED]
            A collection of keys and an array of possible values, '[{'key':'key1','values':['Value1','Value2']},{'key':'Key2','values':['Value3']}]'.
            For example,'[{'key':'Name','values':['TestEC2Instance']}]'.
            (dict) --This data type is used as one of the elements of the ResourceGroup data type.
            key (string) -- [REQUIRED]A tag key.
            value (string) --The value assigned to a tag key.

    :rtype: dict
    :return: {
        'resourceGroupArn': 'string'
    }

    """
    pass


def normals_make_consistent(inside: bool=False):
    """Make face and vertex normals point either outside or inside the mesh

    :param inside: Inside
    :type inside: bool
    """
    pass


def _section(level, title, content, level_chr='=~'):
    """Output a ReST formatted heading followed by the content."""
    return title + '\n' + level_chr[level] * len(title) + '\n\n' + content


def prepare_payload(payload_prep_func, payload):
    """Payload preparation, allowing for python 2/3 compatability"""
    try:
        return bytes(payload_prep_func(payload), 'utf-8')
    except TypeError:
        return payload_prep_func(payload)


def _get_importlib_metadata_metadata(package_name):
    """Retrieve all the metadata for the given package."""
    import sys
    import importlib_metadata
    import json
    result = dict(importlib_metadata.metadata(package_name).items())
    keys = frozenset(('Platform', 'Supported-Platform', 'Classifier',
        'Provides-Dist', 'Requires-Dist', 'Requires-External',
        'Project-URL', 'Provides-Extra'))
    for key in keys:
        value = importlib_metadata.metadata(package_name).get_all(key)
        if value:
            result[key] = value
    print(json.dumps(result))
    sys.exit(0)


def course_enrollment_model():
    """
    Return the student.models.CourseEnrollment model.
    """
    from student.models import CourseEnrollment
    return CourseEnrollment


def divmod_iter_basic(x, by, chunk=None):
    """Generate successive (x % by); x /= by, the obvious way.

    Chunk is ignored.
    """
    while x:
        x, m = divmod(x, by)
        yield m


def is_iterable(thing):
    """Return whether an object is iterable."""
    if hasattr(type(thing), '__iter__'):
        return True
    else:
        try:
            iter(thing)
        except TypeError:
            return False
        else:
            return True


def line_with_key_value(key: str, value: str, line: str) ->bool:
    """
    Both key and value are on the same line
    """
    return key in line and value in line


@classmethod
def get_canonical_name(cls):
    """
        Return the strategy name
        """
    type_ = cls.get_strategy_type()
    name = cls.get_strategy_name()
    return '%s:%s' % (type_, name)


def rows_tag_from_rows(rows):
    """Generate a rows tag, to customize phase names based on the number of rows of data extracted in the fit,
    which is used to speed up serial CTI fits.

    This changes the phase name 'phase_name' as follows:

    rows = None -> phase_name
    rows = (0, 10) -> phase_name_rows_(0,10)
    rows = (20, 60) -> phase_name_rows_(20,60)
    """
    if rows == None:
        return ''
    else:
        x0 = str(rows[0])
        x1 = str(rows[1])
        return '_rows_(' + x0 + ',' + x1 + ')'


def _check_categories(line, categories):
    """ Throws an exception if the line does not match categories
    """
    kw_groups = line.split(',')
    kw_groups.pop(-1)
    if kw_groups != categories:
        raise TypeError('%s is not equal to %s' % (kw_groups, categories))


def iou_1d(predicted_boundary, target_boundary):
    """Calculates the intersection over union (IOU) based on a span.

    Notes:
        boundaries are provided in the the form of [start, stop].
        boundaries where start = stop are accepted
        boundaries are assumed to be only in range [0, int < inf)

        if no intersection, returns 0.

    Example:

        0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 index
           |-----------------------|                                   predicted
                             |------------------------|                target

        then the predicted boundaries are:

            [ lower, upper ]
            [     1,     9 ] predicted
            [     7,    15 ] target

        then the intersection of these two sequences would be:

             2 = 9 - 7
               = min(9, 15) - max(1, 7)
               = min(p_upper, t_upper) - max(p_lower, t_lower)

        and the union:

            14 = 15 - 1
               = max(15, 9) - min(7, 1)
               = max(t_upper, p_upper) - min(t_lower, p_lower)

        giving as IOU of:

            0.143 ≈ 1 / 7 =  2 / 14

    Args:
        predicted_boundary (list): the [start, stop] of the predicted boundary
        target_boundary (list): the ground truth [start, stop] for which to compare

    Returns:
        iou (float): the IOU bounded in [0, 1]

    """
    p_lower, p_upper = predicted_boundary
    t_lower, t_upper = target_boundary
    assert 0 <= p_lower <= p_upper
    assert 0 <= t_lower <= t_upper
    if p_upper < t_lower or p_lower > t_upper:
        return 0
    if predicted_boundary == target_boundary:
        return 1
    intersection_lower_bound = max(p_lower, t_lower)
    intersection_upper_bound = min(p_upper, t_upper)
    intersection = intersection_upper_bound - intersection_lower_bound
    max_upper = max(t_upper, p_upper)
    min_lower = min(t_lower, p_lower)
    union = max_upper - min_lower
    if intersection == 0:
        intersection = 1
    return intersection / union


def unregisterProducer():
    """
        Stop consuming data from a producer, without disconnecting.
        """


def finding_ter(rrnas_in, in_seq_len):
    """
    Finds the positions for Ter based on rRNAs

    :param rrnas_in:    List of rRNA genes from RNAmmer
    :param in_seq_len:  The length of the input FASTA sequence
    :return: Positions for Ter based on rRNAs
    """
    """List for storing the interval coordinates"""
    shift = list()
    for i in range(len(rrnas_in)):
        if i == len(rrnas_in) - 1:
            if rrnas_in[i][2] != rrnas_in[0][2]:
                shift.append(i)
        elif rrnas_in[i][2] != rrnas_in[i + 1][2]:
            shift.append(i)
    if len(shift) != 2:
        return [0, 0]
    elif len(shift) == 2:
        if rrnas_in[shift[1]][2] == 1:
            if shift[1] == len(rrnas_in) - 1:
                ter_start = rrnas_in[shift[1]][1]
                ter_end = rrnas_in[0][0]
                return [ter_start, ter_end]
            else:
                ter_start = rrnas_in[shift[1]][1]
                ter_end = rrnas_in[shift[1] + 1][0]
                return [ter_start, ter_end]
        elif rrnas_in[shift[0]][2] == 1:
            ter_start = rrnas_in[shift[0]][1]
            ter_end = rrnas_in[shift[0] + 1][1]
            return [ter_start, ter_end]


def stream_fastq(file_handler):
    """ Generator which gives all four lines if a fastq read as one string
    """
    next_element = ''
    for i, line in enumerate(file_handler):
        next_element += line
        if i % 4 == 3:
            yield next_element
            next_element = ''


def backup(isamAppliance, check_mode=False, force=False):
    """
    Kickoff Backup of active partition
    """
    if check_mode is True:
        return isamAppliance.create_return_object(changed=True)
    else:
        return isamAppliance.invoke_put('Kickoff Backup of Active Partition',
            '/firmware_settings/kickoff_backup', {})


def subtract(image1, image2, scale=1.0, offset=0):
    """
    Subtracts two images, dividing the result by scale and adding the offset.
    If omitted, scale defaults to 1.0, and offset to 0.0. At least one of the
    images must have mode "1".

    .. code-block:: python

        out = ((image1 - image2) / scale + offset)

    :rtype: :py:class:`~PIL.Image.Image`
    """
    image1.load()
    image2.load()
    return image1._new(image1.im.chop_subtract(image2.im, scale, offset))


def __init__(builder, stepId, args):
    """Create the Command. 'builder' is a reference to the parent
        buildbot_worker.base.WorkerForBuilderBase instance, which will be
        used to send status updates (by calling builder.sendStatus).
        'stepId' is a random string which helps correlate worker logs with
        the master. 'args' is a dict of arguments that comes from the
        master-side BuildStep, with contents that are specific to the
        individual Command subclass.

        This method is not intended to be subclassed."""


def get_unitcell(structure):
    """Wrapper to get the unit cell from different structure classes"""
    from javelin.unitcell import UnitCell
    try:
        return structure.unitcell
    except AttributeError:
        try:
            return UnitCell(structure.lattice.abcABG())
        except AttributeError:
            try:
                from ase.geometry import cell_to_cellpar
                return UnitCell(cell_to_cellpar(structure.cell))
            except (ImportError, AttributeError):
                raise ValueError('Unable to get unit cell from structure')


def interface_method(method):
    """
    Marks method to be included in parsing result.
    """
    method._interface_method = True
    return staticmethod(method)


def clean_dict(dictionary):
    """
    Returns a new but cleaned dictionary.

    * Keys with None type values are removed
    * Keys with empty string values are removed

    This function is designed so we only return useful data
    """
    newdict = dict(dictionary)
    for key in dictionary.keys():
        if dictionary.get(key) is None:
            del newdict[key]
        if dictionary[key] == '':
            del newdict[key]
    return newdict


def str_decode(x: str) ->str:
    """Decodes Unicode encoded as ascii-safe back into a string"""
    return x.encode('utf-8').decode('unicode_escape')


def decode_rate_depth(x: int):
    """return rate and depth from encoded representation"""
    rate = x >> 8
    depth = x & 255
    return rate, depth


def _to_ascii(s):
    """ Converts given string to ascii ignoring non ascii.
    Args:
        s (text or binary):

    Returns:
        str:
    """
    if isinstance(s, str):
        ascii_ = s.encode('ascii', 'ignore')
    elif isinstance(s, bytes):
        ascii_ = s.decode('utf-8').encode('ascii', 'ignore')
    else:
        raise Exception('Unknown text type - {}'.format(type(s)))
    return ascii_


def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
    """Unsets a cookie by name, by default over all domains and paths.

    Wraps CookieJar.clear(), is O(n).
    """
    clearables = []
    for cookie in cookiejar:
        if cookie.name != name:
            continue
        if domain is not None and domain != cookie.domain:
            continue
        if path is not None and path != cookie.path:
            continue
        clearables.append((cookie.domain, cookie.path, cookie.name))
    for domain, path, name in clearables:
        cookiejar.clear(domain, path, name)


def bech32_polymod(values):
    """Internal function that computes the Bech32 checksum."""
    generator = [996825010, 642813549, 513874426, 1027748829, 705979059]
    chk = 1
    for value in values:
        top = chk >> 25
        chk = (chk & 33554431) << 5 ^ value
        for i in range(5):
            chk ^= generator[i] if top >> i & 1 else 0
    return chk


@classmethod
def disable_numba(cls):
    """To disable numba."""
    cls.numba_flag = False


@classmethod
def get_subscriptions(cls, evt=None):
    """Return the handle instances that are subscribed to the specified
        event.  If the event is not specified, return all handles."""
    if evt and cls.subscriptions.has_key(evt):
        return cls.subscriptions[evt]
    return cls.subscriptions


def p_subnet_block(p):
    """ subnet_block : pool_decl
                     | range_stmt
                     | option_decls
                     | pool_decl option_decls
                     | option_decls range_stmt

    """
    p[0] = {}
    for i in range(1, len(p)):
        p[0].update(p[i])


@classmethod
def from_offline_board_entry(cls, board_entry: dict) ->'Board':
    """Construct an Board with data from the offline database snapshot."""
    return cls(board_type=board_entry.get('board_type', ''), board_name=
        board_entry.get('board_name', ''), product_code=board_entry.get(
        'product_code', ''), target_type=board_entry.get('target_type', ''),
        slug=board_entry.get('slug', ''), mbed_os_support=tuple(board_entry
        .get('mbed_os_support', [])), mbed_enabled=tuple(board_entry.get(
        'mbed_enabled', [])), build_variant=tuple(board_entry.get(
        'build_variant', [])))


@classmethod
def get_versions(cls, game):
    """Get versions supported for C{game}."""
    return cls._games[game]


def excludeAllBad(good_i, i, j):
    """Exclude endpoints of BK_i where all pixels are flagged as bad.

    Parameters
    ----------
    good_i: array_like
        1-D array of floats, one for each element along the dispersion
        axis.  The values are 0. or 1., depending on the data quality array
        in the background regions.  If any element in the DQ array in
        column i (in either background region) indicates a bad pixel,
        good_i[i] will be 0 (bad); otherwise, it will be 1 (good).

    i: int
        Lower limit of a slice, i:j excludes the X_OFFSET (as shifted
        depending on the wavecal offset).

    j: int
        Upper limit of a slice.

    Returns
    -------
    tuple of two integers
        New values for i and j, such that good_i[i] and good_i[j-1]
        are both > 0 (if there are any such indices)
    """
    nelem = len(good_i)
    done = False
    ip = i
    while not done:
        if ip >= nelem:
            break
        if good_i[ip] > 0.0:
            done = True
            break
        ip += 1
    if not done:
        ip = i
    done = False
    jp = j - 1
    while not done:
        if jp < ip:
            break
        if good_i[jp] > 0.0:
            done = True
            break
        jp -= 1
    if not done:
        jp = j
    jp += 1
    return ip, jp


@classmethod
def make(cls, poetry, venv, io):
    """Build a wheel in the dist/ directory, and optionally upload it."""
    cls.make_in(poetry, venv, io)


def set_weblog_func(webstreamfunc):
    """
    Set callback method to be called in Dprint, used to show logs in the WEB
    browser.

    See ``bitdust.lib.weblog`` module.
    """
    global _WebStreamFunc
    _WebStreamFunc = webstreamfunc


@classmethod
def set_default_matlab_cmd(cls, matlab_cmd):
    """Set the default MATLAB command line for MATLAB classes.

        This method is used to set values for all MATLAB
        subclasses.  However, setting this will not update the output
        type for any existing instances.  For these, assign the
        <instance>.inputs.matlab_cmd.
        """
    cls._default_matlab_cmd = matlab_cmd


def _compute_regularization(alpha, l1_ratio, regularization):
    """Compute L1 and L2 regularization coefficients for W and H"""
    alpha_H = 0.0
    alpha_W = 0.0
    if regularization in ('both', 'components'):
        alpha_H = float(alpha)
    if regularization in ('both', 'transformation'):
        alpha_W = float(alpha)
    l1_reg_W = alpha_W * l1_ratio
    l1_reg_H = alpha_H * l1_ratio
    l2_reg_W = alpha_W * (1.0 - l1_ratio)
    l2_reg_H = alpha_H * (1.0 - l1_ratio)
    return l1_reg_W, l1_reg_H, l2_reg_W, l2_reg_H


def _dummy_closure(x):
    """
    A dummy function allowing us to build cell objects.
    """
    return lambda : x


def _IREP_prune_metric_cn(cn, rule, pos_idxs, neg_idxs):
    """Returns the prune value of a candidate Rule."""
    P = len(pos_idxs)
    N = len(neg_idxs)
    p = len(cn.rule_covers(rule, pos_idxs))
    n = len(cn.rule_covers(rule, neg_idxs))
    return (p + (N - n)) / (P + N)


@classmethod
def get_config_group_name(cls):
    """Override the get_plugin_name in order to use the document type as
        plugin name. This turns OS::Service::Resource to os_service_resource
        """
    config_name = cls.get_document_type().replace('::', '_').lower()
    return 'resource_plugin:%s' % config_name


def get_element_dict(xpath, var_value=None, var_dim=None,
    include_reference_data=False):
    """
    Function to create a D3.js-type dictionary for a nested tree based on an xpath.

    :param xpath: xpath for the element
    :type xpath: str
    :param var_value: value of the element in a reference file
    :type var_value: float
    :param var_dim: dimension of the element in a reference file
    :type var_dim: int
    :param include_reference_data: setting on whether reference data should be include in the path
    :type include_reference_data: bool
    :return: nested dictionary
    :rtype: dict
    """
    xpath_list = xpath.split('/')[1:]
    xpath_list.reverse()
    max_depth = len(xpath_list) - 1
    for idx, element in enumerate(xpath_list):
        if idx == 0:
            if include_reference_data:
                element_dict = dict(name=element, level=max_depth - idx,
                    type='variable', value=var_value, dimension=var_dim)
            else:
                element_dict = dict(name=element, level=max_depth - idx,
                    type='variable')
        elif idx != max_depth:
            element_dict = dict(name=element, level=max_depth - idx, type=
                'variable', children=[element_dict])
        else:
            element_dict = dict(name=element, level=max_depth - idx,
                children=[element_dict])
    return element_dict


def multiply(iterable):
    """Return product of sequence of numbers.

    Equivalent of functools.reduce(operator.mul, iterable, 1).

    >>> product([2**8, 2**30])
    274877906944
    >>> product([])
    1

    """
    prod = 1
    for i in iterable:
        prod *= i
    return prod


@classmethod
def validate_params(cls):
    """ Called when getting model to validate parameters. Called once per class. """


def _isValid(argname, arg, validArgs=None, condition=None):
    """ Checks that 'arg' is in validArgs and satisfies the given condition. """
    if validArgs is not None:
        if arg not in validArgs:
            print(
                f"Invalid value for '{argname}': '{arg}' is not in the set {validArgs}."
                )
            return False
    if condition is not None:
        validator = eval(f'lambda v: {condition}')
        if validator(arg) is not True:
            print(
                f"Invalid value for '{argname}': '{arg}' does not satisfy '{condition}'."
                )
            return False
    return True


def interval_lengths(bits):
    """
    Get the length distribution of all contiguous runs of set bits from
    """
    end = 0
    while True:
        start = bits.next_set(end)
        if start == bits.size:
            break
        end = bits.next_clear(start)
        yield end - start


def frange(a, b=0, inc=1):
    """Generate sequence of values between a and b inclusive.

    The order of a and b does not matter, only the sign of the increment is
    needed to determine the start and end values of the sequence. If inc is
    positive the starting value will be the smaller of a and b. If inc is
    negative the starting value will be the larger of a and b.

    The sequence ends when the next value would be larger or smaller than the
    end value (depending on direction) and NOT if the next value would equal
    the end value. This is different from Python's built-in range function
    which uses exclusive upper bounds.

    Args:
        a: Either the upper or lower bound.
        b: Optional second bound, defaults to 0.
        inc: incremental difference between consecutive values, defaults to 1.

    Yields:
        The next number in the sequence.

    Raises:
        StopIteration: There are no more values in the sequence.
        ValueError: The increment provided was 0.
    """
    if inc == 0:
        raise ValueError('Increment cannot be 0.')
    elif a + inc == a:
        raise ValueError('Increment is too small.')
    start = min(a, b) if inc > 0 else max(a, b)
    end = max(a, b) if inc > 0 else min(a, b)
    i = 0
    nextval = start
    while inc > 0 and nextval <= end or inc < 0 and nextval >= end:
        yield nextval
        i += 1
        nextval = start + inc * i


@staticmethod
def _on_alarm(signum, _frame):
    """Invoked when the alarm is raised every 5 seconds while processing"""
    pass


def set_alarm_state(AlarmName=None, StateValue=None, StateReason=None,
    StateReasonData=None):
    """
    Temporarily sets the state of an alarm for testing purposes. When the updated state differs from the previous value, the action configured for the appropriate state is invoked. For example, if your alarm is configured to send an Amazon SNS message when an alarm is triggered, temporarily changing the alarm state to ALARM sends an Amazon SNS message. The alarm returns to its actual state (often within seconds). Because the alarm state change happens very quickly, it is typically only visible in the alarm's History tab in the Amazon CloudWatch console or through  DescribeAlarmHistory .
    See also: AWS API Documentation

    :example: response = client.set_alarm_state(
        AlarmName='string',
        StateValue='OK'|'ALARM'|'INSUFFICIENT_DATA',
        StateReason='string',
        StateReasonData='string'
    )

    :type AlarmName: string
    :param AlarmName: [REQUIRED]
            The name for the alarm. This name must be unique within the AWS account. The maximum length is 255 characters.

    :type StateValue: string
    :param StateValue: [REQUIRED]
            The value of the state.

    :type StateReason: string
    :param StateReason: [REQUIRED]
            The reason that this alarm is set to this specific state, in text format.

    :type StateReasonData: string
    :param StateReasonData: The reason that this alarm is set to this specific state, in JSON format.

    """
    pass


@classmethod
def trim(cls, im, vmin=None):
    """@return (yMin, yMax, xMin, xMax)"""
    if vmin is None:
        vmin = im.min()
    xs = im.max(0) > vmin
    ys = im.max(1) > vmin
    xMin = max(0, xs.argmax() - 5)
    yMin = max(0, ys.argmax() - 5)
    xMax = min(len(xs), len(xs) + 5 - xs[::-1].argmax())
    yMax = min(len(ys), len(ys) + 5 - ys[::-1].argmax())
    return yMin, yMax, xMin, xMax


def getFormatExtension():
    """
        returns the filename extension of the format
        """


def files_changed(new_mtimes, initial_mtimes):
    """
    Compares `new_mtimes` with `initial_mtimes` and returns True if
    a key is not in both dicts or the value of a key is not the same.
    """
    for f in new_mtimes:
        if not f in initial_mtimes:
            return True
        elif initial_mtimes[f] != new_mtimes[f]:
            return True
    for f in initial_mtimes:
        if not f in new_mtimes:
            return True
    return False