def encodeCipherString(enctype, iv, ct, mac):
    """return bitwarden cipherstring"""
    ret = '{}.{}|{}'.format(enctype, iv.decode('utf-8'), ct.decode('utf-8'))
    if mac:
        return ret + '|' + mac.decode('utf-8')
    return ret


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 with_name(cls, name, id_user=0, **extra_data):
    """Instantiate a WorkflowEngine given a name or UUID.

        :param name: name of workflow to run.
        :type name: str

        :param id_user: id of user to associate with workflow
        :type id_user: int

        :param module_name: label used to query groups of workflows.
        :type module_name: str
        """
    return cls(name=name, id_user=0, **extra_data)


def _get_old_package_license_ids(migrate_engine):
    """Returns a dict of old license ids, keyed by package id."""
    old_ids = {}
    select_licenses = 'SELECT id, license_id FROM package;'
    q = migrate_engine.execute(select_licenses)
    for id, license_id in q:
        old_ids[id] = license_id
    return old_ids


def restore(delta, which):
    """
    Generate one of the two sequences that generated a delta.

    Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract
    lines originating from file 1 or 2 (parameter `which`), stripping off line
    prefixes.

    Examples:

    >>> diff = ndiff('one\\ntwo\\nthree\\n'.splitlines(keepends=True),
    ...              'ore\\ntree\\nemu\\n'.splitlines(keepends=True))
    >>> diff = list(diff)
    >>> print(''.join(restore(diff, 1)), end="")
    one
    two
    three
    >>> print(''.join(restore(diff, 2)), end="")
    ore
    tree
    emu
    """
    try:
        tag = {(1): '- ', (2): '+ '}[int(which)]
    except KeyError:
        raise ValueError('unknown delta choice (must be 1 or 2): %r' % which)
    prefixes = '  ', tag
    for line in delta:
        if line[:2] in prefixes:
            yield line[2:]


def _receive_all(socket, num_bytes):
    """Reads `num_bytes` bytes from the specified socket.

    :param socket: open socket instance
    :param num_bytes: number of bytes to read

    :return: received data
    """
    buffer = ''
    buffer_size = 0
    bytes_left = num_bytes
    while buffer_size < num_bytes:
        data = socket.recv(bytes_left)
        delta = len(data)
        buffer_size += delta
        bytes_left -= delta
        buffer += data
    return buffer


def duplicate(keep_inputs: bool=False):
    """Duplicate selected nodes

    :param keep_inputs: Keep Inputs, Keep the input links to duplicated nodes
    :type keep_inputs: bool
    """
    pass


def classify_based_on_value(logger_df, field_of_interest, value_of_interest,
    time_step=None, time_symbol='t'):
    """
    Classify the data of a field of interest based on a value of interest.

    Parameters
    ----------
    logger_df: pd.DataFrame
        The logger file in pandas dataframe format.
    field_of_interest: str
        The field of interest that we want to count its different cell types.
    value_of_interest: int
        the value of interest of which the classification will be based on.
    time_step: int (optional)
        The time step between time points. If not specified,
        the time step of the Morpheus file will be used.
    time_symbol: str (default=t)
        The time symbol, as specified in the morpheus model.
    Returns
    -------
    dict_time_series: dict
        A dictionary with cell type as a key, and the occurrences of
        the cell types as a value for different time intervals.
    """
    if not time_step:
        time_steps = logger_df[time_symbol].unique()
        time_step = time_steps[1] - time_steps[0]
    if field_of_interest not in logger_df:
        error_message = 'Column name does not exist!'
        return error_message
    df_size = len(logger_df[time_symbol].unique().tolist())
    dict_time_series = {}
    series_obj = 0
    for j in range(logger_df[time_symbol].unique().tolist()[0], df_size *
        time_step, time_step):
        filtered_data = logger_df[logger_df[time_symbol] == j]
        for i in range(2):
            series_obj = filtered_data.apply(lambda x: True if x[
                field_of_interest] >= value_of_interest else False, axis=1)
            num_of_rows = len(series_obj[series_obj == True].index)
        dict_time_series[j] = [len(series_obj) - num_of_rows, num_of_rows]
    return dict_time_series


def get_field_name_from_lookup(lookup):
    """
    Returns field name from query lookup.
    """
    return lookup.split('__')[0]


def get(name, default=None):
    """ Return the object named by ``name`` or the default.

        ``name`` must be a Unicode object or a bytestring object.

        If ``name`` is a bytestring object, it must be decodable using the
        system default encoding or the UTF-8 encoding.
        """


@classmethod
def _from_et(cls, root, parent):
    """
        Create a :class:`Portref` from a :code:`portref` element.

        :param root: The element tree tree to parse.
        :param parent: :class:`EagleFilePart` that should hold the resulting :class:`EagleFilePart`
        :rtype: :class:`Portref`
        """
    n = cls()
    n._init_from_et(root, parent)
    return n


def guess_contains_nss(lines):
    """Tries to determine if a file includes libnss
    """
    signatures = [
        'Client authentication failed: private key in key database does not match public key in certificate database.'
        ,
        'The next protocol negotiation extension was enabled, but the callback was cleared prior to being needed.'
        , '# SSL/TLS secrets log file, generated by NSS', 'Header: NSS ',
        'Version: NSS ']
    for line in lines:
        for signature in signatures:
            if signature in line:
                return 1
    return 0


@classmethod
def Command(cls, usb, service, command='', timeout_ms=None):
    """One complete set of USB packets for a single command.

    Sends service:command in a new connection, reading the data for the
    response. All the data is held in memory, large responses will be slow and
    can fill up memory.

    Args:
      usb: USB device handle with BulkRead and BulkWrite methods.
      service: The service on the device to talk to.
      command: The command to send to the service.
      timeout_ms: Timeout for USB packets, in milliseconds.

    Raises:
      InterleavedDataError: Multiple streams running over usb.
      InvalidCommandError: Got an unexpected response command.

    Returns:
      The response from the service.
    """
    return ''.join(cls.StreamingCommand(usb, service, command, timeout_ms))


def keys():
    """The keys of the pending event data, all of which are strings."""


def p_exprlist(p):
    """ exprlist : a_expr
                 | exprlist "," a_expr """
    if len(p) == 2:
        p[0] = [p[1]]
    else:
        p[0] = p[1] + [p[3]]


def get_disaggregated_fuel_of_reg(submodel_names, fuel_disagg, region):
    """Get disaggregated region for every submodel
    for a specific region

    Arguments
    -------
    submodel_names : dict
        Name of all submodels
    fuel_disagg : dict
        Fuel per submodel for all regions
    region : str
        Region

    Returns
    -------
    region_fuel_disagg : dict
        Disaggregated fuel for a specific region
    """
    region_fuel_disagg = {}
    for submodel_name in submodel_names:
        region_fuel_disagg[submodel_name] = fuel_disagg[submodel_name][region]
    return region_fuel_disagg


def spline_type_to_id(spline_type):
    """ spline_type_to_id(spline_type)

    Method to map a spline name to an integer ID. This is used so that
    set_cubic_spline_coefs() can be efficient.

    The spline_type can also be a number between -1 and 1, representing
    the tension for a Cardinal spline.
    """
    tension = 0.0
    if isinstance(spline_type, (float, int)):
        if spline_type >= -1 and spline_type <= 1:
            tension = float(spline_type)
            spline_type = 'Cardinal'
        else:
            raise ValueError('Tension parameter must be between -1 and 1.')
    if spline_type.lower() in ['c', 'card', 'cardinal', 'catmull–rom']:
        return tension
    elif spline_type.lower() in ['b', 'basis', 'basic']:
        return 2.0
    elif spline_type.lower() in ['herm', 'hermite']:
        return 3.0
    elif spline_type.lower() in ['lag', 'lagrange']:
        return 4.0
    elif spline_type.lower() in ['lanc', 'lanczos']:
        return 5.0
    elif spline_type.lower() in ['near', 'nearest']:
        return 97.0
    elif spline_type.lower() in ['lin', 'linear']:
        return 98.0
    elif spline_type.lower() in ['quad', 'quadratic']:
        return 99.0
    else:
        raise ValueError('Unknown spline type: ' + str(spline_type))


def check_log_settings(args):
    """
    Quick method to check the consistency of log settings
    from the namespace.
    :param args: a Namespace
    :return: args
    """
    if args.log == 'stderr':
        args.json_conf['log_settings']['log'] = None
    elif args.log is not None:
        args.json_conf['log_settings']['log'] = args.log
    if args.log_level is not None:
        args.json_conf['log_settings']['log_level'] = args.log_level
    elif args.verbose is True:
        args.json_conf['log_settings']['log_level'] = 'DEBUG'
    elif args.noverbose is True:
        args.json_conf['log_settings']['log_level'] = 'ERROR'
    return args


def insertone_query(tablename, objects):
    """
    Function to process the query for insert one  process
    """
    if isinstance(tablename, str):
        pass
    else:
        raise ValueError('Tablename should be a String')
    cols = ''
    for i in tuple(objects.keys()):
        cols += str(i) + ','
    cols = '(' + cols[:len(cols) - 1] + ')'
    if len(objects) == 1:
        if isinstance(list(objects.values())[0], str):
            val = "('" + str(tuple(objects.values())[0]) + "')"
        else:
            val = '(' + str(tuple(objects.values())[0]) + ')'
    else:
        val = str(tuple(objects.values()))
    query = 'INSERT INTO ' + tablename + cols + ' values' + val
    return query


def correct_acc_clutch_on(gear_count, acc, transmission):
    """
    Get the acceleration If clutch is on. Maximum acceleration is
    decreased depending on the transmission.

    :param gear_count:
        Gear count.
    :type gear_count: int

    :param acc:
        Acceleration. (m/s2)
    :type acc:

    :param transmission:
        Transmission type.
    :type transmission: str

    :return:
        Acceleration when clutch on. (m/s2)
    :rtype:
    """
    if gear_count > 0:
        if transmission == 'manual':
            return 0.0
        else:
            return acc * 2 / 3
    else:
        return acc


def get_all_results():
    """Return a dictionary mapping pathname (a tuple of strings, ready to
        be slash-joined) to an ICheckAndRepairResults instance, one for each
        object that was checked."""


def select_linked(deselect: bool=False):
    """Select bones related to selected ones by parent/child relationships

    :param deselect: Deselect
    :type deselect: bool
    """
    pass


def describe_affected_entities(filter=None, locale=None, nextToken=None,
    maxResults=None):
    """
    Returns a list of entities that have been affected by the specified events, based on the specified filter criteria. Entities can refer to individual customer resources, groups of customer resources, or any other construct, depending on the AWS service. Events that have impact beyond that of the affected entities, or where the extent of impact is unknown, include at least one entity indicating this.
    At least one event ARN is required. Results are sorted by the lastUpdatedTime of the entity, starting with the most recent.
    See also: AWS API Documentation

    :example: response = client.describe_affected_entities(
        filter={
            'eventArns': [
                'string',
            ],
            'entityArns': [
                'string',
            ],
            'entityValues': [
                'string',
            ],
            'lastUpdatedTimes': [
                {
                    'from': datetime(2015, 1, 1),
                    'to': datetime(2015, 1, 1)
                },
            ],
            'tags': [
                {
                    'string': 'string'
                },
            ],
            'statusCodes': [
                'IMPAIRED'|'UNIMPAIRED'|'UNKNOWN',
            ]
        },
        locale='string',
        nextToken='string',
        maxResults=123
    )

    :type filter: dict
    :param filter: [REQUIRED]
            Values to narrow the results returned. At least one event ARN is required.
            eventArns (list) -- [REQUIRED]A list of event ARNs (unique identifiers). For example: 'arn:aws:health:us-east-1::event/AWS_EC2_MAINTENANCE_5331', 'arn:aws:health:us-west-1::event/AWS_EBS_LOST_VOLUME_xyz'
            (string) --
            entityArns (list) --A list of entity ARNs (unique identifiers).
            (string) --
            entityValues (list) --A list of IDs for affected entities.
            (string) --
            lastUpdatedTimes (list) --A list of the most recent dates and times that the entity was updated.
            (dict) --A range of dates and times that is used by the EventFilter and EntityFilter objects. If from is set and to is set: match items where the timestamp (startTime , endTime , or lastUpdatedTime ) is between from and to inclusive. If from is set and to is not set: match items where the timestamp value is equal to or after from . If from is not set and to is set: match items where the timestamp value is equal to or before to .
            from (datetime) --The starting date and time of a time range.
            to (datetime) --The ending date and time of a time range.

            tags (list) --A map of entity tags attached to the affected entity.
            (dict) --
            (string) --
            (string) --

            statusCodes (list) --A list of entity status codes (IMPAIRED , UNIMPAIRED , or UNKNOWN ).
            (string) --

    :type locale: string
    :param locale: The locale (language) to return information in. English (en) is the default and the only supported value at this time.

    :type nextToken: string
    :param nextToken: If the results of a search are large, only a portion of the results are returned, and a nextToken pagination token is returned in the response. To retrieve the next batch of results, reissue the search request and include the returned token. When all results have been returned, the response does not contain a pagination token value.

    :type maxResults: integer
    :param maxResults: The maximum number of items to return in one batch, between 10 and 100, inclusive.

    :rtype: dict
    :return: {
        'entities': [
            {
                'entityArn': 'string',
                'eventArn': 'string',
                'entityValue': 'string',
                'awsAccountId': 'string',
                'lastUpdatedTime': datetime(2015, 1, 1),
                'statusCode': 'IMPAIRED'|'UNIMPAIRED'|'UNKNOWN',
                'tags': {
                    'string': 'string'
                }
            },
        ],
        'nextToken': 'string'
    }

    :returns:
    (string) --
    (string) --

    """
    pass


def read_mm_stamp(fh, byteorder, dtype, count):
    """Read MM_STAMP tag from file and return as numpy.array."""
    return fh.read_array(byteorder + 'f8', 8)


@staticmethod
def _dummyOnData(interest, data):
    """
        This is a do-nothing onData for using expressInterest for timeouts.
        This should never be called.
        """
    pass


def _non_linear_lspline(wcs_dict):
    """Returns a linear spline model of the wavelength solution

    Not implemented

    This function should extract certain parameters from the `wcs_dict`
    parameter and construct a mathematical model that makes the conversion from
    pixel to wavelength. All the necessary information is already contained in
    the dictionary so the only work to be done is to make the instantiation of
    the appropriate subclass of `~astropy.modeling.Model`.

    Parameters
    ----------

        wcs_dict : dict
            Contains all the WCS information decoded from an IRAF fits header.

    Raises
    ------

        NotImplementedError
    """
    raise NotImplementedError('Linear spline is not implemented')


def square(x: float) ->float:
    """Return the square of a provided number."""
    return x * x


@staticmethod
def _parse_unit(unit):
    """Return the flux and velocity units for integrating spectra."""
    try:
        flux, velo = unit.split(' ')
    except ValueError:
        flux, velo = unit, None
    if flux.lower() not in ['mjy', 'jy', 'mk', 'k', 'mjy/beam', 'jy/beam']:
        raise ValueError('Unknown flux unit: {}.'.format(flux))
    if velo is not None and velo.lower() not in ['m/s', 'km/s']:
        raise ValueError('Unknown velocity unit: {}'.format(velo))
    if velo is not None:
        velo = velo.lower()
    return flux.lower(), velo


def githubpath(user, repo, path, name):
    """Build a valid URL to file on Github.

    Note: This is sensitive to changes in how Github URLs work.

    Arguments:
    user -- the Github user ID/name
    repo -- the Github user's repository name
    path -- specific path to file within the repo
    name -- specific file name or gist id

    Returns URL to Github file or gist.
    """
    if user != '' and repo != '':
        retval = 'https://github.com/{0}/{1}/blob/master/'.format(user, repo)
    else:
        retval = 'https://gist.github.com/'
    if path:
        retval += path
        if name not in path:
            retval += '/' + name
    else:
        retval += name
    return retval


@classmethod
def _parse_and_normalize_offers(cls, offers):
    """
        Throw out any offers that do not match the media range ABNF.

        :return: A list of offers split into the format ``[offer_index,
                 parsed_offer]``.

        """
    parsed_offers = []
    for index, offer in enumerate(offers):
        try:
            parsed_offer = cls.parse_offer(offer)
        except ValueError:
            continue
        parsed_offers.append([index, parsed_offer])
    return parsed_offers


def calc_weight_pso(x, *args):
    """
    Calculating the current weight
    :param current_dict:
    :return:
    """
    width = args[5]
    span = args[6]
    plate_area = width * x[1]
    stiff_area = (x[2] * x[3] + x[4] * x[5]) * (width // x[0])
    return span * 7850 * (plate_area + stiff_area)


@staticmethod
def _generate_crc7(data):
    """ Generate a 7-bit CRC """
    return 0


def two_way_clamp(lower, upper, value):
    """ A function that accepts a lower and upper bound and a value
        and will return the value if it is between the bounds, or it
        will return the clamped value.

        >>> two_way_clamp(100, 500, 250)
        250

        >>> two_way_clamp(100, 500, -40)
        100

        >>> two_way_clamp(-100, -500, 0)
        -100
    """
    if lower > upper:
        upper, lower = lower, upper
    return max(lower, min(upper, value))


def twos_complement(val, bits):
    """Retuns the 2-complemented value of val assuming bits word width"""
    if val & 1 << bits - 1 != 0:
        val = val - 2 ** bits
    return val


def at_content(seq):
    """Return AT Content of Sequence"""
    result = float(str(seq).count('A') + str(seq).count('T')) / len(seq) * 100
    return result


def get_all_projects_basic_info(tb_client, project_id):
    """
    获取所有项目基础信息 project_id, project_name, organization_id, default_room_id
    :param tb_client: Teambition object
    :param project_id: Teambition object
    :return:
    """
    if project_id is None:
        projects = tb_client.get_projects_basic_info()
    else:
        projects = [tb_client.get_project_basic_info(project_id)]
    project_infos = []
    for project in projects:
        default_room = tb_client.get_project_group_chat_info(project_id=
            project['_id'])
        project_infos.append({'project_id': project['_id'], 'name': project
            ['name'], 'root_dir_id': project['_rootCollectionId'],
            'organization_id': project['_organizationId'],
            'default_room_id': default_room['_id']})
    return project_infos


def intersect_line_line(v1: 'mathutils.Vector', v2: 'mathutils.Vector', v3:
    'mathutils.Vector', v4: 'mathutils.Vector'):
    """Returns a tuple with the points on each line respectively closest to the other.

    :param v1: First point of the first line
    :type v1: 'mathutils.Vector'
    :param v2: Second point of the first line
    :type v2: 'mathutils.Vector'
    :param v3: First point of the second line
    :type v3: 'mathutils.Vector'
    :param v4: Second point of the second line
    :type v4: 'mathutils.Vector'
    """
    pass


def returns_boolean(func):
    """
    Method decorator that hints the collection class of
    an entity that the method returns a boolean.
    """
    func.returns_boolean = True
    return func


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 prep(stg, ns='{http://www.topografix.com/GPX/1/1}'):
    """
    This modifies the namespace path thingy so it works. I'm a bit hazy on
    exactly what's happening here, but this works so I'm going with it for now.

    This function could probably dispensed with if I deal with the namespace
    correctly. I should read the [lxml
    documentation](http://lxml.de/tutorial.html) better and also refer to [this
    post](http://stackoverflow.com/questions/37964570/read-gpx-using-lxml-and-xpath).
    [This post](http://stackoverflow.com/questions/18071387/read-gpx-using-python-elementtree-register-namespace) seems even more on topic.
    """
    return ns + stg.replace('/', '/' + ns)


def _total_microsec(t1, t2):
    """
    Calculate difference between two datetime stamps in microseconds.

    :type t1: :class: `datetime.datetime`
    :type t2: :class: `datetime.datetime`
    :return: int

    .. rubric:: Example

    >>> from obspy import UTCDateTime
    >>> print(_total_microsec(UTCDateTime(2013, 1, 1).datetime,
    ...                       UTCDateTime(2014, 1, 1).datetime))
    -31536000000000
    """
    td = t1 - t2
    return (td.seconds + td.days * 24 * 3600) * 10 ** 6 + td.microseconds


def mag_to_object_dist(efl, mag):
    """Compute the object distance for a given focal length and magnification.

    Parameters
    ----------
    efl : `float`
        focal length of the lens
    mag : `float`
        signed magnification

    Returns
    -------
    `float`
        object distance

    """
    return efl * (1 / mag + 1)


def memory_free(library, session, offset, extended=False):
    """Frees memory previously allocated using the memory_allocation() operation.

    Corresponds to viMemFree* function of the VISA library.

    :param library: the visa library wrapped by ctypes.
    :param session: Unique logical identifier to a session.
    :param offset: Offset of the memory to free.
    :param extended: Use 64 bits offset independent of the platform.
    :return: return value of the library call.
    :rtype: :class:`pyvisa.constants.StatusCode`
    """
    if extended:
        return library.viMemFreeEx(session, offset)
    else:
        return library.viMemFree(session, offset)


@staticmethod
def _parse_message(message):
    """Extracts required attributes out of the messages properties.

        This extracts the `reply_to` and the `correlation_id` properties. If
        any of these required properties are missing a `ValueError` is raised.
        """
    properties = []
    for prop in ('reply_to', 'correlation_id'):
        try:
            properties.append(message.properties[prop])
        except KeyError:
            raise ValueError("The '%s' message property is missing" % prop)
    return properties


def subtract(x, y):
    """Subtract Function"""
    return x - y


def to_fb(f, b):
    """Simply call f(b)"""
    return f(b)


def byte_string_valid_encoding(byte_string, encoding='utf-8'):
    """Detect if a byte :class:`bytes` is valid in a specific encoding

    :arg byte_string: Byte :class:`bytes` to test for bytes not valid in this
        encoding
    :kwarg encoding: encoding to test against.  Defaults to :term:`UTF-8`.
    :returns: :data:`True` if there are no invalid :term:`UTF-8` characters.
        :data:`False` if an invalid character is detected.

    .. note::

        This function checks whether the byte :class:`bytes` is valid in the
        specified encoding.  It **does not** detect whether the byte
        :class:`bytes` actually was encoded in that encoding.  If you want that
        sort of functionality, you probably want to use
        :func:`~kitchen.text.misc.guess_encoding` instead.
    """
    try:
        str(byte_string, encoding)
    except UnicodeError:
        return False
    return True


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

        :param TfaRemoveSecurityKeyType val:
        :rtype: EventType
        """
    return cls('tfa_remove_security_key', val)


def test_analytical_vs_numerical():
    """Test by comparing analytical and numerical values.

    >>> flag='c'
    >>> S=1000.0
    >>> K=1000.0
    >>> t=0.1
    >>> r=0.05
    >>> sigma=0.3
    >>> q = 0.05
    >>> sigma = 0.2
    >>> flag = 'c'

    >>> epsilon = 0.01

    >>> v1 = delta(flag, S, K, t, r, sigma, q)
    >>> v2 = adelta(flag, S, K, t, r, sigma, q)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = gamma(flag, S, K, t, r, sigma, q)
    >>> v2 = agamma(flag, S, K, t, r, sigma, q)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = rho(flag, S, K, t, r, sigma, q)
    >>> v2 = arho(flag, S, K, t, r, sigma, q)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = vega(flag, S, K, t, r, sigma, q)
    >>> v2 = avega(flag, S, K, t, r, sigma, q)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = theta(flag, S, K, t, r, sigma, q)
    >>> v2 = atheta(flag, S, K, t, r, sigma, q)
    >>> abs(v1-v2)<epsilon
    True

    Test PUT flag

    >>> flag = 'p'

    >>> v1 = delta(flag, S, K, t, r, sigma, q)
    >>> v2 = adelta(flag, S, K, t, r, sigma, q)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = gamma(flag, S, K, t, r, sigma, q)
    >>> v2 = agamma(flag, S, K, t, r, sigma, q)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = rho(flag, S, K, t, r, sigma, q)
    >>> v2 = arho(flag, S, K, t, r, sigma, q)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = vega(flag, S, K, t, r, sigma, q)
    >>> v2 = avega(flag, S, K, t, r, sigma, q)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = theta(flag, S, K, t, r, sigma, q)
    >>> v2 = atheta(flag, S, K, t, r, sigma, q)
    >>> abs(v1-v2)<epsilon
    True
    """
    pass


@staticmethod
def _get_absolute(event):
    """Get the absolute (pixel) location of the mouse cursor."""
    return event.locationInWindow()


def _content_types(element):
    """Return an hashable value representing the element content type (string or ordered tuple of
    types).
    """
    if isinstance(element.textual_content_type, set):
        if 'Unknown' in element.textual_content_type:
            element.textual_content_type.remove('Unknown')
        if len(element.textual_content_type) == 1:
            element.textual_content_type = element.textual_content_type.pop()
            return element.textual_content_type
        return tuple(sorted(element.textual_content_type))
    return element.textual_content_type


def _cut_time(gammas):
    """Support function for iat().
    Find cutting time, when gammas become negative."""
    for i in range(len(gammas) - 1):
        if not (gammas[i + 1] > 0.0) & (gammas[i + 1] < gammas[i]):
            return i
    return i


def modify_db_cluster_snapshot_attribute(DBClusterSnapshotIdentifier=None,
    AttributeName=None, ValuesToAdd=None, ValuesToRemove=None):
    """
    Adds an attribute and values to, or removes an attribute and values from, a manual DB cluster snapshot.
    To share a manual DB cluster snapshot with other AWS accounts, specify restore as the AttributeName and use the ValuesToAdd parameter to add a list of IDs of the AWS accounts that are authorized to restore the manual DB cluster snapshot. Use the value all to make the manual DB cluster snapshot public, which means that it can be copied or restored by all AWS accounts. Do not add the all value for any manual DB cluster snapshots that contain private information that you don't want available to all AWS accounts. If a manual DB cluster snapshot is encrypted, it can be shared, but only by specifying a list of authorized AWS account IDs for the ValuesToAdd parameter. You can't use all as a value for that parameter in this case.
    To view which AWS accounts have access to copy or restore a manual DB cluster snapshot, or whether a manual DB cluster snapshot public or private, use the  DescribeDBClusterSnapshotAttributes API action.
    See also: AWS API Documentation

    Examples
    The following example gives two AWS accounts access to a manual DB cluster snapshot and ensures that the DB cluster snapshot is private by removing the value "all".
    Expected Output:

    :example: response = client.modify_db_cluster_snapshot_attribute(
        DBClusterSnapshotIdentifier='string',
        AttributeName='string',
        ValuesToAdd=[
            'string',
        ],
        ValuesToRemove=[
            'string',
        ]
    )

    :type DBClusterSnapshotIdentifier: string
    :param DBClusterSnapshotIdentifier: [REQUIRED]
            The identifier for the DB cluster snapshot to modify the attributes for.

    :type AttributeName: string
    :param AttributeName: [REQUIRED]
            The name of the DB cluster snapshot attribute to modify.
            To manage authorization for other AWS accounts to copy or restore a manual DB cluster snapshot, set this value to restore .

    :type ValuesToAdd: list
    :param ValuesToAdd: A list of DB cluster snapshot attributes to add to the attribute specified by AttributeName .
            To authorize other AWS accounts to copy or restore a manual DB cluster snapshot, set this list to include one or more AWS account IDs, or all to make the manual DB cluster snapshot restorable by any AWS account. Do not add the all value for any manual DB cluster snapshots that contain private information that you don't want available to all AWS accounts.
            (string) --

    :type ValuesToRemove: list
    :param ValuesToRemove: A list of DB cluster snapshot attributes to remove from the attribute specified by AttributeName .
            To remove authorization for other AWS accounts to copy or restore a manual DB cluster snapshot, set this list to include one or more AWS account identifiers, or all to remove authorization for any AWS account to copy or restore the DB cluster snapshot. If you specify all , an AWS account whose account ID is explicitly added to the restore attribute can still copy or restore a manual DB cluster snapshot.
            (string) --

    :rtype: dict
    :return: {
        'DBClusterSnapshotAttributesResult': {
            'DBClusterSnapshotIdentifier': 'string',
            'DBClusterSnapshotAttributes': [
                {
                    'AttributeName': 'string',
                    'AttributeValues': [
                        'string',
                    ]
                },
            ]
        }
    }

    :returns:
    (string) --

    """
    pass


@classmethod
def coerce(cls, key, value):
    """Given a value, coerce it into the target type.

        Can be overridden by custom subclasses to coerce incoming
        data into a particular type.

        By default, raises ``ValueError``.

        This method is called in different scenarios depending on if
        the parent class is of type :class:`.Mutable` or of type
        :class:`.MutableComposite`.  In the case of the former, it is called
        for both attribute-set operations as well as during ORM loading
        operations.  For the latter, it is only called during attribute-set
        operations; the mechanics of the :func:`.composite` construct
        handle coercion during load operations.

        :param key: string name of the ORM-mapped attribute being set.
        :param value: the incoming value.
        :return: the method should return the coerced value, or raise
         ``ValueError`` if the coercion cannot be completed.

        """
    if value is None:
        return None
    msg = "Attribute '%s' does not accept objects of type %s"
    raise ValueError(msg % (key, type(value)))


@staticmethod
def get_parser(parser_factory, file_path):
    """
        Gets parser for given file

        :param parser_factory:
        :param file_path: path to file to be parsed
        :type file_path: str
        :return: parser
        :rtype: SafeConfigParser
        """
    parser = parser_factory.create_parser()
    parser.optionxform = str
    parser.read(file_path)
    return parser


def mrw_url(debug=False):
    """
    MRW URL connection

    :param debug: If set to true, use Envialia test URL
    """
    if debug:
        return 'http://sagec-test.mrw.es/MRWEnvio.asmx'
    else:
        return 'https://sagec.mrw.es/MRWEnvio.asmx'


def replace_colon(s, replacewith='__'):
    """replace the colon with something"""
    return s.replace(':', replacewith)


@classmethod
def clean_templates(cls, action, instance, pk_set, **kwargs):
    """
        adds organization validation
        """
    templates = cls.clean_templates_org(action, instance, pk_set, **kwargs)
    super().clean_templates(action, instance, templates, **kwargs)


@staticmethod
def _reward_while_pending():
    """Defines the reward value which is assigned to config, while it is pending."""
    return float('-inf')


def _group_merge_refs(proto_op_dag, merge_refs):
    """
    Takes the protbuf representation of the operator dag together with the merge references and converts them into
    grouped merge references, which is pairs of (to-op-index, from-op-index).
    Two ops can be merged if:
      - All inputs of the to-op come from one and the same from-op.
      - OR inputs can come from external inputs.
    :param proto_op_dag: the protobuf representation of the operator dag.
    :param merge_refs: merge references.
    :return: pairs of (to-op-index, from-op-index).
    """
    merge_group_info = set()
    for merge_ref in merge_refs:
        merge_group_info.add((merge_ref.to_op_index, merge_ref.
            from_op_index, merge_ref.from_out_arg_index))
    group_merge_refs = []
    for i, reference in enumerate(proto_op_dag.references):
        if len(reference.input_refs) == 0:
            continue
        from_op_index = reference.input_refs[0].op_index
        if from_op_index == i:
            continue
        to_op_index = i
        do_group = True
        for in_ref in reference.input_refs:
            if in_ref.is_leaf:
                continue
            if in_ref.op_index != from_op_index:
                do_group = False
                break
            from_out_arg_index = in_ref.op_output_index
            if (to_op_index, from_op_index, from_out_arg_index
                ) not in merge_group_info:
                do_group = False
                break
        if do_group:
            group_merge_refs.append((to_op_index, from_op_index))
    return group_merge_refs


@staticmethod
def _nested_lookup(doc, field):
    """
        Performs a nested lookup of doc using a period (.) delimited
        list of fields.  This is a nested dictionary lookup.
        :param doc: document to perform lookup on
        :param field: period delimited list of fields
        :return:
        """
    value = doc
    keys = field.split('.')
    try:
        for k in keys:
            value = value[k]
    except KeyError:
        return None
    return str(value)


def sort_branch_list(branch_labels, ref_branch_label='control'):
    """Order branch labels for plotting, consistently.

    The control branch goes last because some plots include a series
    for it, and some plots don't, and we want the colors to be
    consistent between these plots.
    """
    assert ref_branch_label in branch_labels
    return sorted(set(branch_labels) - {ref_branch_label}) + [ref_branch_label]


def scan_setup_py():
    """Validate the contents of setup.py against Versioneer's expectations."""
    found = set()
    setters = False
    errors = 0
    with open('setup.py', 'r') as f:
        for line in f.readlines():
            if 'import versioneer' in line:
                found.add('import')
            if 'versioneer.get_cmdclass()' in line:
                found.add('cmdclass')
            if 'versioneer.get_version()' in line:
                found.add('get_version')
            if 'versioneer.VCS' in line:
                setters = True
            if 'versioneer.versionfile_source' in line:
                setters = True
    if len(found) != 3:
        print('')
        print('Your setup.py appears to be missing some important items')
        print('(but I might be wrong). Please make sure it has something')
        print('roughly like the following:')
        print('')
        print(' import versioneer')
        print(' setup( version=versioneer.get_version(),')
        print('        cmdclass=versioneer.get_cmdclass(),  ...)')
        print('')
        errors += 1
    if setters:
        print("You should remove lines like 'versioneer.VCS = ' and")
        print("'versioneer.versionfile_source = ' . This configuration")
        print('now lives in setup.cfg, and should be removed from setup.py')
        print('')
        errors += 1
    return errors


@classmethod
def items(cls):
    """Return the associated L{pyxb.binding.facet._EnumerationElement} instances."""
    return list(cls.iteritems())


def set_testmode(testing):
    """Sets the package testing mode.
    """
    global testmode
    testmode = testing


@staticmethod
def sort_plugins(plugins_list):
    """
        Sorts loaded Artella Launcher plugins taking into account their order attribute
        :param plugins_list: list(ArtellaLauncherPlugin)
        :return: list(ArtellaLauncherPlugin)
        """
    if not isinstance(plugins_list, list):
        raise TypeError('Artella Launcher Plugins must be of type list!')
    plugins_list.sort(key=lambda p: p.ORDER)
    return plugins_list


def start():
    """Begin the encode/upload process. This involves reading encrypted
        data from the IEncryptedUploadable, encoding it, uploading the shares
        to the shareholders, then sending the hash trees.

        set_encrypted_uploadable() and set_shareholders() must be called
        before this can be invoked.

        This returns a Deferred that fires with a verify cap when the upload
        process is complete. The verifycap, plus the encryption key, is
        sufficient to construct the read cap.
        """


def get_plural_string(word: str, amount: int) ->str:
    """Returns singular or plural of the word depending on the amount.
	Example:
		word = 'piece', amount = 0 -> '0 pieces'
		word = 'piece', amount = 1 -> '1 piece'
		word = 'piece', amount = 5 -> '5 pieces'"""
    if amount == 1:
        return f'1 {word}'
    else:
        return f'{amount} {word}s'


def adapt_gene_id(gene_id, longest_gene_number_length):
    """
    Input: a gene ID like g_1 and the longest_gene_number_length (5 if you have a gene like g_12356).
    Return a new gene ID with a completion of 0 like: g_00001.
    """
    gene_prefix = '_'.join(gene_id.split('_')[:-1])
    gene_number = gene_id.split('_')[-1]
    new_gene_id = gene_prefix + '_' + gene_number.zfill(
        longest_gene_number_length)
    return new_gene_id


def drop_pair(attrs, key='default'):
    """
    >>> attrs = ['default', 'none', 'nonull', 'load']
    >>> drop_pair(attrs)
    ['nonull', 'load']
    """
    if key in attrs:
        idx = attrs.index(key)
        del attrs[idx:idx + 2]
    return attrs


@classmethod
def create(cls, value=None, signal=None):
    """
        Create an instance of either a return value or an exit signal.
        The other parameter must be None.
        """
    if value is None and signal is None:
        raise ValueError('Need return value or exit signal for ProcessExitCode'
            )
    if value is not None and signal is not None:
        raise ValueError(
            'Cannot create ProcessExitCode with both value and signal')
    if value is not None and not 0 <= value <= 255:
        raise ValueError('Invalid value {} for return value'.format(value))
    if signal is not None and not 1 <= signal <= 127:
        raise ValueError('Invalid value {} for exit signal'.format(value))
    exitcode = (value or 0) * 256 + (signal or 0)
    return cls(exitcode, value, signal)


def redo():
    """Redo previous action

    """
    pass


def isinstance_safe(value, type_):
    """Determine if value is a subclass of type_

    Will work even if it is not a valid question to ask of
    the given value.
    """
    try:
        return isinstance(value, type_)
    except TypeError:
        return False


def text_paste():
    """Paste text from clipboard

    """
    pass


@staticmethod
def _to_python_type(variable):
    """
        Returns the value in the variable handling also np.array of one element

        :param variable: input variable
        :return: the value of the variable having a python type (int, float, ...)
        """
    try:
        return variable.item()
    except AttributeError:
        return variable


def flatten_fieldsets(fieldsets):
    """Returns a list of field names from an admin fieldsets structure."""
    field_names = []
    for name, opts in fieldsets:
        for field in opts['fields']:
            if type(field) == tuple:
                field_names.extend(field)
            else:
                field_names.append(field)
    return field_names


@staticmethod
def _get_size_data(c_data: dict) ->int:
    """From a chapter data, retrieve size"""
    return int(len(c_data['page_array']))


def _resolve(name):
    """Resolve a dotted name to a global object."""
    name = name.split('.')
    used = name.pop(0)
    found = __import__(used)
    for n in name:
        used = used + '.' + n
        try:
            found = getattr(found, n)
        except AttributeError:
            __import__(used)
            found = getattr(found, n)
    return found


@classmethod
def from_httplib(cls, message):
    """Read headers from a Python 2 httplib message object."""
    headers = []
    for line in message.headers:
        if line.startswith((' ', '\t')):
            key, value = headers[-1]
            headers[-1] = key, value + '\r\n' + line.rstrip()
            continue
        key, value = line.split(':', 1)
        headers.append((key, value.strip()))
    return cls(headers)


def is_debug_mode() ->bool:
    """Debug mode enables extra logging and assertions, but is slower."""
    return False


@classmethod
def is_site_in_topic(cls) ->bool:
    """True if site id is in topic."""
    return True


def share_mask(mask):
    """Flag a chan,integration if any pol/baseline has flagged it."""
    m = {}
    for pol in mask:
        for bl in mask[pol]:
            for t in mask[pol][bl]:
                m[t] = m.get(t, 0) | mask[pol][bl]
    for pol in mask:
        for bl in mask[pol]:
            for t in mask[pol][bl]:
                mask[pol][bl][t] = m[t]
    return mask


def statistics(input_dict):
    """
    Statistics of Annotated Document Corpus.

    :param adc: Annotated Document Corpus.
    :return doc_count (int): Number of Documents.
    :return feature_count (int): Number of Features.
    :return description (string): Statistics.
    """
    output_dict = {}
    output_dict['doc_count'] = len(input_dict['adc'].documents)
    output_dict['feature_count'] = len(input_dict['adc'].features)
    output_dict['description'] = 'Number of documents is ' + str(output_dict
        ['doc_count']) + ', number of corpus features is ' + str(output_dict
        ['feature_count']) + '.'
    return output_dict


def _get_middle(token):
    """Return float given a string possibly including 'S'.

    Parameters
    ----------
    token : str
        String representation of middle layer_ ints, floats symmetric
        e.g. '800', '800.0', '400S'

    Examples
    --------
    >>> _get_middle('800.0')
    800.0
    >>> _get_middle('400S')
    800.0

    Notes
    -----
    The symmetry flag 'S' indicates doubling the numeric value.

    """
    if 'S' in token:
        return 2 * float(token[:-1])
    else:
        return float(token)


def dict_sum(items):
    """Construct a dict, in between dict(items) and sum(items), by accumulating items for each key."""
    d = {}
    for k, v in items:
        if k not in d:
            d[k] = v
        else:
            d[k] += v
    return d


def split_data(data):
    """
    Split the matrix in 2 matrices one for sense the other for antisense.

    :param data: the coverage data to split
    :type data: a 2 dimension :class:`pandas.DataFrame` object
    :return: two matrix
    :rtype: tuple of two :class:`pandas.DataFrame` object (sense pandas.DataFrame, antisense pandas.DataFrame)
    """
    grp = data.groupby(by=['sense'])
    return grp.get_group('S').copy(), grp.get_group('AS').copy()


@classmethod
def _remove_duplicates(cls, seq):
    """
        Remove duplicates in a case insensitive, but case preserving manner.
        """
    tmpd = {}
    for item in seq:
        if item.lower() not in tmpd:
            tmpd[item.lower()] = True
            yield item


def p_xor_expr_1(p):
    """xor_expr : and_expr"""
    p[0] = p[1]


def reveal(select: bool=True):
    """Reveal all hidden UV vertices

    :param select: Select
    :type select: bool
    """
    pass


@classmethod
def set_lock(cls, lock):
    """Set the global lock."""
    cls._lock = lock


def SetDrawingDefaults(drawingData):
    """Add required items into data['drawing'] array if not present. This does not add
    all the items in SetupDrawingData, but it seems that this is not a problem. Perhaps the
    two routines could be combined?
    """
    defaultDrawing = {'viewPoint': [[0.5, 0.5, 0.5], []], 'showHydrogen':
        True, 'backColor': [0, 0, 0], 'depthFog': False, 'Zclip': 50.0,
        'cameraPos': 50.0, 'Zstep': 0.5, 'radiusFactor': 0.85,
        'contourLevel': 1.0, 'bondRadius': 0.1, 'ballScale': 0.33,
        'vdwScale': 0.67, 'ellipseProb': 50, 'sizeH': 0.5, 'unitCellBox':
        True, 'showABC': True, 'selectedAtoms': [], 'Atoms': [], 'oldxy': [
        ], 'magMult': 1.0, 'bondList': {}, 'viewDir': [1, 0, 0], 'Plane': [
        [0, 0, 1], False, False, 0.0, [255, 255, 0]]}
    for key in defaultDrawing:
        if key not in drawingData:
            drawingData[key] = defaultDrawing[key]


@classmethod
def _to_str(cls, value):
    """Represents values either as string or None values as empty string.

        Args:
            value: a value

        """
    if value is None:
        return ''
    else:
        return str(value)


def content_item(path1, path2, path_sep='/'):
    """
    if path1 is subpart of path2, get the next path item.
    example:
    path1 = '/foo'
    path2 = '/foo/bar/foo'
    -> 'bar'

    """
    p1_parts = path1.split(path_sep)
    p2_parts = path2.split(path_sep)
    if path1 == path_sep and len(p2_parts) >= 2:
        return p2_parts[1]
    if len(p2_parts) <= len(p1_parts):
        return ''
    for i, item in enumerate(p1_parts):
        if item != p2_parts[i]:
            return ''
    return p2_parts[i + 1]


@classmethod
def _get_creatable_subclass_by_tagnames(cls):
    """Returns the possible sub classes addable to this class
        """
    dic = {}
    for c in cls._choice_classes:
        dic.update(c._get_creatable_class_by_tagnames())
    return dic


def _ri2py(obj):
    """ Dummy function for ri2py.

    This function will convert Python objects into Python (presumably non-rpy2) objects.
    """
    raise NotImplementedError(
        "Conversion 'ri2py' not defined for objects of type '%s'" % str(
        type(obj)))


@classmethod
def get_auth_providers(cls):
    """Returns list of auth_providers used within test.

        Tests may redefine this method to include their own or third party
        client auth_providers.
        """
    return [cls.os_primary.auth_provider]


def create_zpaq(archive, compression, cmd, verbosity, interactive, filenames):
    """Create a ZPAQ archive."""
    cmdlist = [cmd, 'a', archive]
    cmdlist.extend(filenames)
    cmdlist.extend(['-method', '4'])
    return cmdlist


def lmroman(pic_name):
    """
    horrible hack to use LMRoman typeface in svg figure

    Never got it to work with  plt.rcParams["font.family"] = "LMRoman10"
    """
    import subprocess
    cmd = ['sed', '-i', 's/DejaVu\\ Sans/LMRoman10/', pic_name]
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    output, error = process.communicate()


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

        :param FileAddCommentDetails val:
        :rtype: EventDetails
        """
    return cls('file_add_comment_details', val)


@classmethod
def supports_from_pcm(cls):
    """returns True if all necessary components are available
        to support the .from_pcm() classmethod"""
    try:
        from audiotools.encoders import encode_mp3
        return True
    except ImportError:
        return False


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '.post.dev%d' % pieces['distance']
    else:
        rendered = '0.post.dev%d' % pieces['distance']
    return rendered


@staticmethod
def validate(sr):
    """
        Simple sanity check
        :param sr:
        :return:
        """
    assert int(sr.annotations['size']) == len(sr)
    assert sr.annotations['start'] + sr.annotations['size'
        ] - 1 <= sr.annotations['srcSize']


def booleanformat(value):
    """
    Format a boolean value
    """
    if isinstance(value, bool):
        if value == True:
            return 'true'
        elif value == False:
            return 'false'
    else:
        return value


def switch_direction():
    """Switch direction of selected splines

    """
    pass


def add_seq2fa(sequence_data, file_output, write_mode='a'):
    """Add sequences to a file, in Fasta Format.

    Parameters
    ----------
    sequence_data : str, array_like
        Sequence to add to the fasta file. if only the sequence is provided,
    assume the header is not relevant and a random will be created, sequence base
    to avoid collisions

        sequence_data[0] == Header or id of the sequences, if do not contain > ,
    it will be added.
        sequence_data[1] == Sequence

    file_output: str, obj
        This function can recive both a file_handler or file name. In the former
        scenario it will create a file_handler, and in both cases it will let
        it open, to improve I/O.

    Returns
    -------

    file_handle : obj
        returns the file handler.

    Raises
    ------
    ValueError
        Sequence_data should contain two items: header, Sequece

    Examples
    --------

         write_fasta_sequence('ATGATGATGA','my_file.fasta')

         write_fasta_sequence('ATGATGATGA',open('my_file.fasta', 'a'))

         write_fasta_sequence(['SEQ_1', 'ATGATGATGA'],'my_file.fasta')

    """
    if isinstance(sequence_data, str):
        header = sequence_data.strip('\n').strip()[:100]
        sequence_data = [header, sequence_data.strip('\n').strip()]
    if not len(sequence_data) >= 2:
        raise ValueError(
            'Sequence data must contain at least header and sequence')
    if isinstance(file_output, str):
        file_handle = open(file_output, write_mode)
    else:
        file_handle = file_output
    file_handle.write('>{0}\n{1}\n'.format(*sequence_data))
    return file_handle


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


@classmethod
def close_registry_entry(cls, value):
    """Close a registry entry."""
    return False


@staticmethod
def int_to_bytestring(i, padding=8):
    """
        Turns an integer to the OATH specified
        bytestring, which is fed to the HMAC
        along with the secret
        """
    result = bytearray()
    while i != 0:
        result.append(i & 255)
        i >>= 8
    return bytes(bytearray(reversed(result)).rjust(padding, b'\x00'))


@staticmethod
def _draw_vline(**kwargs):
    """Draw a grid of vertical lines."""
    for x in range(0, kwargs['im_width'], kwargs['grid_size']):
        kwargs['grid'].line([(min(max(x, kwargs['padding_left']), kwargs[
            'im_width'] - kwargs['padding_right']), max(0, kwargs[
            'padding_top'])), (min(max(x, kwargs['padding_left']), kwargs[
            'im_width'] - kwargs['padding_right']), kwargs['im_height'] -
            kwargs['padding_bottom'])], fill=kwargs['grid_colour'], width=
            kwargs['line_width'])


def get_ext_info(hdu):
    """
    Returns name, type and size of a specified HDU extension

    :param hdu: a single extension of a multiextension HDU item
    :type hdu: astropy.io.fits.hdu.image class
    :return: 3- element dictionary with text values for extension name, extension type, and extension size.
    """
    outDict = {}
    outDict['name'] = hdu.name
    outDict['type'] = str(hdu).split(' object')[0].split('.')[-1]
    if outDict['type'] == 'ImageHDU' and hdu.shape:
        outDict['size'] = '{} x {}'.format(hdu.shape[0], hdu.shape[1])
    elif 'table' in outDict['type'].lower():
        nRows = len(hdu.data)
        nCols = len(hdu.data[0])
        outDict['size'] = '{}R x {}C'.format(nRows, nCols)
    else:
        outDict['size'] = '()'
    return outDict


def cache_clear(cache):
    """Clears cache with the given name.

    :param str|unicode cache: Cache name with optional address (if @-syntax is used).

    :rtype: None
    """


@classmethod
def header_hash(cls, header):
    """Given a header return the hash."""
    import x13_hash
    return x13_hash.getPoWHash(header)


def p_scalar_value_list(p):
    """SCALAR_VALUE_LIST : SCALAR_VALUE
                         | SCALAR_VALUE_LIST COMMA SCALAR_VALUE"""
    if len(p) > 2:
        p[1].append(p[3])
        p[0] = p[1]
    else:
        p[0] = [p[1]]


def receptor_bound(pdb_code):
    """Augment pdb code with receptor partner and bound binding notation."""
    return pdb_code + '_r_b'


def perms_are_transitive(p):
    """
    Test whether the group generated by the permutations in ``p`` is transitive.

    INPUT:

    - ``p`` - a list of permutations of `[0, n-1]`

    EXAMPLES::

        sage: from surface_dynamics.misc.permutation import perms_are_transitive
        sage: perms_are_transitive([[0,1,2],[0,2,1]])
        False
        sage: perms_are_transitive([[0,1,2],[1,2,0]])
        True

        sage: p0 = [0,2,3,1,7,5,6,4]
        sage: p1 = [7,1,2,3,4,5,6,0]
        sage: p2 = [6,1,2,3,4,5,0,7]
        sage: p3 = [1,0,2,3,4,5,6,7]
        sage: p4 = [0,1,4,5,2,3,6,7]
        sage: perms_are_transitive([p0,p1,p2,p3,p4])
        True
        sage: perms_are_transitive([p0,p1,p2,p3])
        False
    """
    if not p:
        raise ValueError('empty list')
    n = len(p[0])
    if n <= 1:
        return True
    cc0 = [False] * n
    todo = [0]
    cc0[0] = True
    while todo:
        j = todo.pop()
        for pp in p:
            k = pp[j]
            if cc0[k] is False:
                todo.append(k)
                cc0[k] = True
    return all(j is True for j in cc0)


def get_key_from_dict(dict, value):
    """Takes a dict and a value, returns a list with matching keys."""
    try:
        return list(dict.keys())[list(dict.values()).index(value)]
    except ValueError:
        return None


@classmethod
def from_fqdn(cls, fqdn):
    """Retrieve domain id associated to a FQDN."""
    result = cls.list({'fqdn': fqdn})
    if len(result) > 0:
        return result[0]['id']


def list(client, user_id, group_id):
    """Get security credentials of  user."""
    credentials = client.user.credentials.list(method='GET', userId=user_id,
        groupId=group_id)
    return credentials


def format_heading(level, text):
    """Create a heading of <level> [1, 2 or 3 supported]."""
    underlining = {(0): '', (1): '=', (2): '-', (3): '~'}
    return '{}\n{}\n\n'.format(text, underlining[level] * len(text))


def readcomments(filename, comment='#'):
    """
    Reads in filename and extracts only data that contains the comments
    parameter.

    Reference
    ---------
    https://stackoverflow.com/a/39724905/8765762
    """
    comments_all = []
    with open(filename, 'r') as cmt_file:
        for line in cmt_file:
            if line[0] == comment:
                comments_all.append(line[1:])
    return comments_all


def interpolate_history_as_isothermal_intervals(tTpath):
    """Takes the time-temperature path specification and subdivides it for
    calculation in isothermal intervals.

    Does it based on model of Ketcham et al., in review.
    It is calibrated to facilitate 0.5% accuracy for end-member F-apatite by
    having a maximum temperature step of 3.5 degrees C when the model
    temperature is within 10 C of the total annealing temperature.  Before this
    cutoff the maximum temperature step required is 8 C.  If the overall model
    time steps are too large, these more distant requirements may not be met.
    """
    total_time = tTpath.totaltime
    rate = tTpath.rate
    abs_rate = abs(rate)
    def_timestep = total_time / 100.0
    return tTpath


@classmethod
def meta(cls):
    """Return a dictionary containing meta-information about the given
        resource."""
    if getattr(cls, '__from_class__', None) is not None:
        cls = cls.__from_class__
    attribute_info = {}
    for name, value in cls.__table__.columns.items():
        attribute_info[name] = str(value.type).lower()
    return {cls.__name__: attribute_info}


def is_int(arg):
    """Returns True if the arg is an integer value"""
    return arg == int(arg)


def with_siblings(graph, outputs):
    """Include all missing siblings."""
    siblings = set()
    for node in outputs:
        siblings |= graph.siblings(node)
    return siblings


def bezier_point(p0: float, p1: float, p2: float, p3: float, t: float):
    """
    Calculate the position of a point with parameter t on the cubic bezier curve.

    Note that the parameter t must >=0 and <=1 .

    :param p0: position of the first control point
    :param p1: position of the second control point
    :param p2: position of the third control point
    :param p3: position of the forth control point
    :param t: the parameter t
    :return: position of the point
    """
    if t < 0 or t > 1:
        raise ValueError('t must in [0..1]')
    return (1 - t) ** 3 * p0 + 3 * (1 - t) ** 2 * t * p1 + 3 * (1 - t
        ) * t ** 2 * p2 + t ** 3 * p3


def dbh__svg_image(path, contenttype, extension, roottag, nsurl):
    """ Generic Web Page Handler - Returns image_generic for Web browser supported images """
    if extension.lower() in ['svg'] or contenttype.startswith('image/svg+xml'):
        return 'db_svg_viewer'
    else:
        return False


def filter_none(attribute, default):
    """Handle attributes of model components that are optional in SBML."""
    if attribute is None:
        return default
    else:
        return attribute


def match_items(lines, content_old):
    """Create items for mangled lines.

    This function tries to match the lines in ``lines`` with the items (source
    file references and line numbers) in ``content_old``. The
    ``mangle_docstrings`` function changes the actual docstrings, but doesn't
    keep track of where each line came from. The manging does many operations
    on the original lines, which are hard to track afterwards.

    Many of the line changes come from deleting or inserting blank lines. This
    function tries to match lines by ignoring blank lines. All other changes
    (such as inserting figures or changes in the references) are completely
    ignored, so the generated line numbers will be off if ``mangle_docstrings``
    does anything non-trivial.

    This is a best-effort function and the real fix would be to make
    ``mangle_docstrings`` actually keep track of the ``items`` together with
    the ``lines``.

    Examples
    --------
    >>> lines = ['', 'A', '', 'B', '   ', '', 'C', 'D']
    >>> lines_old = ['a', '', '', 'b', '', 'c']
    >>> items_old = [('file1.py', 0), ('file1.py', 1), ('file1.py', 2),
    ...              ('file2.py', 0), ('file2.py', 1), ('file2.py', 2)]
    >>> content_old = ViewList(lines_old, items=items_old)
    >>> match_items(lines, content_old) # doctest: +NORMALIZE_WHITESPACE
    [('file1.py', 0), ('file1.py', 0), ('file2.py', 0), ('file2.py', 0),
     ('file2.py', 2), ('file2.py', 2), ('file2.py', 2), ('file2.py', 2)]
    >>> # first 2 ``lines`` are matched to 'a', second 2 to 'b', rest to 'c'
    >>> # actual content is completely ignored.

    Notes
    -----
    The algorithm tries to match any line in ``lines`` with one in
    ``lines_old``.  It skips over all empty lines in ``lines_old`` and assigns
    this line number to all lines in ``lines``, unless a non-empty line is
    found in ``lines`` in which case it goes to the next line in ``lines_old``.

    """
    items_new = []
    lines_old = content_old.data
    items_old = content_old.items
    j = 0
    for i, line in enumerate(lines):
        while j < len(lines_old) - 1 and not lines_old[j].strip():
            j += 1
        items_new.append(items_old[j])
        if line.strip() and j < len(lines_old) - 1:
            j += 1
    assert len(items_new) == len(lines)
    return items_new


def resolve_name(name):
    """Resolve a name like ``module.object`` to an object and return it.

    Raise `ImportError` if the module or name is not found.
    """
    parts = name.split('.')
    cursor = len(parts) - 1
    module_name = parts[:cursor]
    attr_name = parts[-1]
    while cursor > 0:
        try:
            ret = __import__('.'.join(module_name), fromlist=[attr_name])
            break
        except ImportError:
            if cursor == 0:
                raise
            cursor -= 1
            module_name = parts[:cursor]
            attr_name = parts[cursor]
            ret = ''
    for part in parts[cursor:]:
        try:
            ret = getattr(ret, part)
        except AttributeError:
            raise ImportError(name)
    return ret


def S_ISDOOR(mode):
    """Return True if mode is from a door."""
    return False


def rmdir(path, recursive=True, **kwargs):
    """Remove the directory *path*"""
    if recursive:
        import shutil
        return shutil.rmtree(path, **kwargs)
    else:
        import os
        return os.remdir(path, **kwargs)


def _extract_value(field_name, raw_xml):
    """Extract a value from raw xml

    Simplistic string parsing version...
    """
    val = raw_xml.split('%s>' % field_name)[1].rstrip('</')
    return val


def parse_sml(response):
    """Parse the json for a SML Hue motion sensor and return the data."""
    if response['type'] == 'ZLLLightLevel':
        lightlevel = response['state']['lightlevel']
        if lightlevel is not None:
            lux = round(float(10 ** ((lightlevel - 1) / 10000)), 2)
            dark = response['state']['dark']
            daylight = response['state']['daylight']
            data = {'light_level': lightlevel, 'lux': lux, 'dark': dark,
                'daylight': daylight}
        else:
            data = {'light_level': 'No light level data'}
    elif response['type'] == 'ZLLTemperature':
        if response['state']['temperature'] is not None:
            data = {'temperature': response['state']['temperature'] / 100.0}
        else:
            data = {'temperature': 'No temperature data'}
    elif response['type'] == 'ZLLPresence':
        name_raw = response['name']
        arr = name_raw.split()
        arr.insert(-1, 'motion')
        name = ' '.join(arr)
        hue_state = response['state']['presence']
        if hue_state is True:
            state = 'on'
        else:
            state = 'off'
        data = {'model': 'SML', 'name': name, 'state': state, 'battery':
            response['config']['battery'], 'last_updated': response['state'
            ]['lastupdated'].split('T')}
    return data


@staticmethod
def parse_identifier(uri):
    """ Extract canonical post id/url (i.e. strip any leading `@`). """
    return '@%s' % uri.split('@')[-1]


def decimal_to_percent(value, decimal_place=2):
    """
    Format a decimal to percentage with two decimal
    :param value: the value to be formatted
    :param decimal_place default decimal place, default to 2
    :return: a string in percentage format, 20.50% etc
    """
    format_str = '{:.' + str(2) + '%}'
    return format_str.format(value)


@classmethod
def get_table(cls, name):
    """Return DynamoDB Table object"""
    if name not in cls._table_cache:
        cls._table_cache[name] = cls.resource().Table(name)
    return cls._table_cache[name]


def selector(zelf, *args, **kwargs):
    """ see if this things has the desired attributes. """
    wanted = args[0]
    if not wanted:
        return False
    go = False
    for arg in wanted:
        if arg in zelf and zelf[arg]:
            go = True
            break
    return go


@staticmethod
def _query_const_from_list_subroutine(expr_list):
    """
        A sub method for _query_construction_from_list method in aiding query construction
        :param expr_list: list, relevance query list
        :return: str
        """
    interim_list = []
    interim_str = None
    for index, each_exp_list in enumerate(expr_list):
        for each_exp in each_exp_list:
            interim_list.append(each_exp)
        if index == len(expr_list) - 1:
            interim_str = '({})'.format(' OR '.join(interim_list))
    return interim_str


@classmethod
def from_isotherm(cls, isotherm, pressure=None, loading=None, isotherm_data
    =None, pressure_key=None, loading_key=None, other_keys=None):
    """
        Construct a point isotherm using a parent isotherm as the template for
        all the parameters.

        Parameters
        ----------
        isotherm : Isotherm
            An instance of the Isotherm parent class.
        pressure : list
            Create an isotherm directly from an array. Values for pressure.
            If the ``isotherm_data`` dataframe is specified, these values are ignored.
        loading : list
            Create an isotherm directly from an array. Values for loading.
            If the ``isotherm_data`` dataframe is specified, these values are ignored.
        isotherm_data : DataFrame
            Pure-component adsorption isotherm data.
        loading_key : str
            Column of the pandas DataFrame where the loading is stored.
        pressure_key : str
            Column of the pandas DataFrame where the pressure is stored.
        """
    iso_params = isotherm.to_dict()
    iso_params['pressure'] = pressure
    iso_params['loading'] = loading
    iso_params['isotherm_data'] = isotherm_data
    iso_params['pressure_key'] = pressure_key
    iso_params['loading_key'] = loading_key
    iso_params['other_keys'] = other_keys
    return cls(**iso_params)


def _is_pesummary_json_file(path, check_function):
    """Determine if the result file is a pesummary json file

    Parameters
    ----------
    path: str
        path to the results file
    check_function: func
        function used to check the result file
    """
    import json
    with open(path, 'r') as f:
        data = json.load(f)
    return check_function(data)


def _create_color_generator():
    """Create a generator which will cycle through a list of default matplotlib colors"""
    from itertools import cycle
    colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd',
        '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf']
    return cycle(colors)


@staticmethod
def __replace_base_variables(text, req_len, idx):
    """
        Replace i and n in text with index+1 and req_len.

        :param text: base text to modify
        :param req_len: amount of required resources
        :param idx: index of resource we are working on
        :return: modified string
        """
    return text.replace('{i}', str(idx + 1)).replace('{n}', str(req_len))


def create_fields(field_meta_data: list):
    """ metaprogramming script that returns the dictionary of attributes for a type model data class """
    attributes = {}
    for field in field_meta_data:
        kw_args = []
        if 'title' in field.keys():
            kw_args.append('title="%s"' % field['title'])
        if 'description' in field.keys():
            kw_args.append('description="%s"' % field['description'])
        if 'default' in field.keys():
            if type(field['default']) == str:
                kw_args.append('default="%s"' % field['default'])
            else:
                kw_args.append('default=%s' % field['default'])
        for k, v in field['attributes'].items():
            if k not in ('name', 'type'):
                if type(v) == str:
                    kw_args.append('%s="%s"' % (k, v))
                else:
                    kw_args.append('%s=%s' % (k, v))
        validator = eval('validators.%s(%s)' % (field['type'], ', '.join(
            kw_args)))
        attributes[field['name']] = validator
    return attributes


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

        :param FileRequestsChangePolicyDetails val:
        :rtype: EventDetails
        """
    return cls('file_requests_change_policy_details', val)


def slot_obj_dict(o):
    """
    Builds dict for o with __slots__ defined
    :param o:
    :return:
    """
    d = {}
    for f in o.__slots__:
        d[f] = getattr(o, f, None)
    return d


@staticmethod
def _get_prefix(path):
    """Get the appropriate prefix for the given file"""
    try:
        idx = path.rindex('/')
    except ValueError:
        try:
            idx = path.index('.')
        except ValueError:
            idx = len(path)
    return path[:idx].strip('/').replace('/', '_')


def create_pivot_df(df_snp):
    """constructs pivot DataFrame
     grouping data by the duplex variant
     """
    context_data = df_snp.groupby('ref_duplex').sum()
    context_data.drop(['start_pos', 'stop_pos'], inplace=True, axis=1)
    return context_data


def runscgi(func, addr=('0.0.0.0', 4000)):
    """Runs a WSGI function as an SCGI server."""
    import flup.server.scgi as flups
    return flups.WSGIServer(func, bindAddress=addr, debug=False).run()


@staticmethod
def slice_state_history(states, slice_length):
    """Slices states from the trackers history.

        If the slice is at the array borders, padding will be added to ensure
        the slice length."""
    slice_end = len(states)
    slice_start = max(0, slice_end - slice_length)
    padding = [None] * max(0, slice_length - slice_end)
    state_features = padding + states[slice_start:]
    return state_features


@classmethod
def _long_cheshvan(cls, year):
    """Returns True if Cheshvan has 30 days"""
    return cls._days_in_year(year) % 10 == 5


def get_dir_edges_from_c_to_tars(c_to_tars):
    """
    returns tuple of all allowed directed edges (c, t) where c control
    and t target.

    Parameters
    ----------
    c_to_tars : dict[int, list[int]]
        a dictionary mapping j in range(num_bits) to a list, possibly
        empty, of the physically allowed targets of qubit j, when j is
        the control of a CNOT.

    Returns
    -------
    tuple[tuple[int, int]]

    """
    dir_edges = []
    for c, tars in c_to_tars.items():
        for t in tars:
            dir_edges.append((c, t))
    return tuple(dir_edges)


def rgbHex(r, g, b: int):
    """
    rgb to hex converter
    Arguments: r = red channel
               g = green channel
               b = blue channel

    Pass in the Value sequentialy
    """
    assert r <= 255 and r >= 0
    assert g <= 255 and g >= 0
    assert b <= 255 and b >= 0
    r = format(r, 'x').zfill(2)
    g = format(g, 'x').zfill(2)
    b = format(b, 'x').zfill(2)
    hex_string = '#%s%s%s' % (r, g, b)
    return hex_string


def url_to_advert(url, frame_type, tx_power):
    """
    Encode as specified
    https://github.com/google/eddystone/blob/master/eddystone-url/README.md
    :param url:
    :return:
    """
    prefix_sel = None
    prefix_start = None
    prefix_end = None
    suffix_sel = None
    suffix_start = None
    suffix_end = None
    prefix = 'http://www.', 'https://www.', 'http://', 'https://'
    suffix = ('.com/', '.org/', '.edu/', '.net/', '.info/', '.biz/',
        '.gov/', '.com', '.org', '.edu', '.net', '.info', '.biz', '.gov')
    encode_search = True
    for x in prefix:
        if x in url and encode_search is True:
            prefix_sel = prefix.index(x)
            prefix_start = url.index(prefix[prefix_sel])
            prefix_end = len(prefix[prefix_sel]) + prefix_start
            encode_search = False
    encode_search = True
    for y in suffix:
        if y in url and encode_search is True:
            suffix_sel = suffix.index(y)
            suffix_start = url.index(suffix[suffix_sel])
            suffix_end = len(suffix[suffix_sel]) + suffix_start
            encode_search = False
    service_data = [frame_type]
    service_data.extend([tx_power])
    if suffix_start is None:
        suffix_start = len(url)
        service_data.extend([prefix_sel])
        for x in range(prefix_end, suffix_start):
            service_data.extend([ord(url[x])])
    elif suffix_end == len(url):
        service_data.extend([prefix_sel])
        for x in range(prefix_end, suffix_start):
            service_data.extend([ord(url[x])])
        service_data.extend([suffix_sel])
    else:
        service_data.extend([prefix_sel])
        for x in range(prefix_end, suffix_start):
            service_data.extend([ord(url[x])])
        service_data.extend([suffix_sel])
        for x in range(suffix_end, len(url)):
            service_data.extend([ord(url[x])])
    return service_data


def bases_to_complete_next_codon(phase):
    """
    Return the bases at the exon end that completes the next codon.

    >>> bases_to_complete_next_codon(0) # e.g. -----XXX
    0
    >>> bases_to_complete_next_codon(2) # e.g. XX-----X
    2
    >>> bases_to_complete_next_codon(1) # e.g. X-----XX
    1
    """
    if phase in {0, 1, 2}:
        return phase
    raise ValueError('Only phases 0, 1 and 2 are allowed.')


def add_period(event_dict, event):
    """
    Add period for event

    :param event_dict: dict of event info
    :param event: list with parsed event info

    :return: None
    """
    try:
        event_dict['Period'] = int(event[1])
    except ValueError:
        event_dict['Period'] = 0


def _remove_checksum(lines):
    """Remove metadata comments giving a checksum.

    Adblock Plus is no longer verifying checksums, so we don't have to
    calculate the checksum for the resulting filter list. But we have
    to strip them for compatibility with older versions of Adblock Plus
    and other ad blockers which might still verify a checksum if given.
    """
    for line in lines:
        if line.type != 'metadata' or line.key.lower() != 'checksum':
            yield line


def right_arrow_path(x, y, offset):
    """ x,y is the final point
    """
    d = [('m', x - 2 * offset, y), (offset, 0), (0, -offset), (offset,
        offset), (-offset, offset), (0, -offset), 'z']
    return d


def psi_K_MgOH_HSO4_HMW84(T, P):
    """c-c'-a: potassium magnesium-hydroxide bisulfate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def guess_contains_png(lines):
    """Tries to determine if a file includes png
    """
    for line in lines:
        if 'libpng error: %s, offset=%d' in line:
            return 1
        if (
            'Application uses deprecated png_write_init() and should be recompiled'
             in line):
            return 1
        if 'libpng version ' in line:
            return 1
    return 0


def v110_shadowserver_feednames(defaults, runtime, harmonization, dry_run):
    """
    Replace deprecated Shadowserver feednames
    """
    mapping = {'Botnet-Drone-Hadoop': 'Drone', 'DNS-open-resolvers':
        'DNS-Open-Resolvers', 'Open-NetBIOS': 'Open-NetBIOS-Nameservice',
        'Ssl-Freak-Scan': 'SSL-FREAK-Vulnerable-Servers', 'Ssl-Scan':
        'SSL-POODLE-Vulnerable-Servers'}
    changed = None
    for bot_id, bot in runtime.items():
        if bot['module'] == 'intelmq.bots.parsers.shadowserver.parser':
            if bot['parameters']['feedname'] in mapping:
                changed = True
                bot['parameters']['feedname'] = mapping[bot['parameters'][
                    'feedname']]
    return changed, defaults, runtime, harmonization


def is_from_parent(cls, attribute_name, value=None):
    """
    Tests if the current attribute value is shared by a parent of the given
    class.

    Returns None if the attribute value is None.

    :param cls: Child class with the requested attribute
    :param attribute_name: Name of the attribute to be tested
    :param value: The exact value in the child class (optional)
    :return: True if the attribute value is shared with a parent class
    """
    if value is None:
        try:
            value = getattr(cls, attribute_name)
        except AttributeError:
            return False
    for base in cls.__bases__:
        try:
            return getattr(base, attribute_name) is value
        except AttributeError:
            pass
    return False


def should_insert_line_break_at(position, line_length=80):
    """
    For given ``position`` in string, should we insert line break?
    """
    if line_length > 0 and position:
        return position % line_length == 0
    return False


def to_dict(key, value):
    """
    Creates a dict from a dot-separated path-style key and a value.

    Examples:
    "foo", "bar" => "baz"
    "foo.bar", "baz" => {"foo"{"bar":"baz}}
    """
    key_parts = key.split('.')
    result = {}
    current = result
    for key_part in key_parts[:-1]:
        current = current.setdefault(key_part, {})
    current[key_parts[-1]] = value
    return result


@classmethod
def _extract_job_id(cls, text):
    """Extract JobID from Condor Output."""
    try:
        return text.strip().split()[-1][0:-1]
    except IndexError:
        return None


@classmethod
def obj_name(cls):
    """Return the object's name

        Return a canonical name for this object which will be used over
        the wire for remote hydration.
        """
    return cls.__name__


def set_red(pix, r):
    """Set the red value of Pixel pix to r."""
    pix.set_red(r)


def _l_diversity(x):
    """
        A simple implementation of l-diversity counting na as distinct values

        Aggarwal, Charu C.; Yu, Philip S. (2008):
        "A General Survey of Privacy"
        http://charuaggarwal.net/generalsurvey.pdf
        Springer. ISBN 978-0-387-70991-8
    """
    nb_distinct_without_na = x.nunique(dropna=True)
    nb_of_na = sum(x.isnull())
    return nb_distinct_without_na + nb_of_na


def iteration():
    """
    Returns the number of iterations since the current top-level sequence started.

    Returns:
        int: iteration count.

    """
    from niveristand.library._tasks import get_scheduler
    return get_scheduler().get_task_for_curr_thread().iteration_counter.count


def get_user_name(user, full_name=True):
    """Return the user's name as a string.
    Full names by default.
    """
    try:
        if full_name:
            name = ' '.join([user.first_name, user.last_name])
        else:
            name = user.first_name
    except AttributeError:
        name = None
    return name


def has_resource(resource_name):
    """Does the package contain the named resource?"""


def to_bytes(arg):
    """Converts arg to a 'bytes' object."""
    if type(arg) is bytes:
        return arg
    elif type(arg) is list:
        return bytes(bytearray(arg))
    elif type(arg) is str:
        return arg.encode('utf-8')
    else:
        return bytearray(arg)


@classmethod
def _test_boundaries(cls, value):
    """Test if value is within defined range for this object."""
    return cls.value_min <= value <= cls.value_max


@staticmethod
def hasMetadata(cls):
    """ Check if the given class *cls* has a metadata

            :param cls: the entity class
            :type  cls: type
            :rtype:     bool
        """
    return '__tdbm__' in dir(cls)


def get_object_parent(cmis_id):
    """Return a list of objects that are all parents of the one
        specified by its id. Stop at the root of the connector.
        """


def version():
    """
  show version info.
  """
    print('wbsv 0.1.6')


def canon(raw_attr_name: str) ->str:
    """
    Canonicalize input attribute name as it appears in proofs and credential offers: strip out
    white space and convert to lower case.

    :param raw_attr_name: attribute name
    :return: canonicalized attribute name
    """
    if raw_attr_name:
        return raw_attr_name.replace(' ', '').lower()
    return raw_attr_name


def decode_response(client_message, to_object=None):
    """ Decode response from client message"""
    parameters = dict(response=None)
    parameters['response'] = client_message.read_bool()
    return parameters


def p_cdtextfile(t):
    """cdtextfile : CDTEXTFILE STRING"""
    t[0] = 'cdtextfile', t[2]


def p_data_chunk1(p):
    """
    data_chunk : data_chunk data_chunk
    """
    p[0] = p[1] + p[2]


def _loss(dz, gamma=0.15):
    """Risk / Loss function, Tanaka et al. (https://arxiv.org/abs/1704.05988)

    Parameters
    ----------
    gamma : float

    Returns
    -------
    loss : float
    """
    return 1 - 1 / (1 + (dz / gamma) ** 2)


def getElementProperties():
    """Return a dictionary of this element's properties."""


@property
@classmethod
def scheme(cls):
    """The scheme defines where this Observation can be looked up.

        Only 'caom' is currently supported."""
    return cls._SCHEME


def whitespace_tokenize(text):
    """Runs basic whitespace cleaning and splitting on a piece of text."""
    text = text.strip()
    if not text:
        return []
    tokens = text.split()
    return tokens


@classmethod
def getVolumeProps(cls):
    """Intended to be overridden by sub-classes as needed.  Returns a list
        of property names which control the currently displayed
        volume/timepoint for 4D overlays. The default implementation returns
        an empty list.
        """
    return []


def GET_to_bool(request, key):
    """
    Parses a GET parameter in the request as bool.
    "true" becomes True, "false" becomes False, "null" becomes None.

    :param request: the request
    :type  request: django.http.HttpRequest

    :param key: the key in request.GET
    :type  key: str

    :return: Boolean or None
    :rtype : bool | None
    """
    clone_manual = request.GET[key]
    assert clone_manual in ['true', 'false', 'null']
    clone_manual_bool = None
    if clone_manual == 'true':
        clone_manual_bool = True
    if clone_manual == 'false':
        clone_manual_bool = False
    return clone_manual_bool


def register_sentry(sentry_dsn):
    """Given a Raven client and an RQ worker, registers exception handlers
    with the worker so exceptions are logged to Sentry.
    """
    import sentry_sdk
    from sentry_sdk.integrations.rq import RqIntegration
    sentry_sdk.init(sentry_dsn, integrations=[RqIntegration()])


@staticmethod
def calc_population_density(population: int, area: int) ->(int, None):
    """ Calculating the Population Density given the Population and Area """
    if population is not None and area is not None:
        return population // area


def info_header(label):
    """Make a nice header string."""
    return '--{:-<60s}'.format(' ' + label + ' ')


@staticmethod
def invert_y(z, y):
    """
        Inverts the Y tile value.

        Inputs:
        z -- the zoom level associated with the tile
        y -- the Y tile number

        Returns:
        The flipped tile value
        """
    return (1 << z) - y - 1


def gmsh_grid_adapt2D(out_dim=(100.0, 100.0), in_dim=(50.0, 50.0), out_res=
    (10.0, 10.0), in_res=(5.0, 5.0), out_pos=(0.0, 0.0), in_pos=(25.0, 25.0
    ), z_pos=0.0):
    """Generate the 2D mesh adapter."""
    try:
        from pygmsh import Geometry
    except ImportError:
        from pygmsh.built_in import Geometry
    geo = Geometry()
    code = ['outx = {};'.format(out_dim[0]), 'outy = {};'.format(out_dim[1]
        ), 'inx = {};'.format(in_dim[0]), 'iny = {};'.format(in_dim[1]),
        'grioutx = {};'.format(out_res[0]), 'griouty = {};'.format(out_res[
        1]), 'grix = {};'.format(in_res[0]), 'griy = {};'.format(in_res[1]),
        'obx = {};'.format(out_pos[0]), 'oby = {};'.format(out_pos[1]),
        'ibx = {};'.format(in_pos[0]), 'iby = {};'.format(in_pos[1]),
        'bz = {};'.format(z_pos),
        'Point(1) = {obx,       oby,        bz,         grioutx};',
        'Point(2) = {obx+outx,  oby,        bz,         grioutx};',
        'Point(3) = {obx+outx,  oby+outy,   bz,         grioutx};',
        'Point(4) = {obx,       oby+outy,   bz,         grioutx};',
        'Point(9) =  {ibx,      iby,        bz,         grix};',
        'Point(10) = {ibx+inx,  iby,        bz,         grix};',
        'Point(11) = {ibx+inx,  iby+iny,    bz,         grix};',
        'Point(12) = {ibx,      iby+iny,    bz,         grix};',
        'Line(1) = {1, 2}; //s top', 'Line(2) = {2, 3}; //e top',
        'Line(3) = {3, 4}; //n top', 'Line(4) = {4, 1}; //w top',
        'Line(13) = {9, 10}; //s top', 'Line(14) = {10, 11}; //e top',
        'Line(15) = {11, 12}; //n top', 'Line(16) = {12, 9}; //w top',
        'Line Loop(26) = {1, 2, 3, 4};',
        'Line Loop(27) = {13, 14, 15, 16};',
        'Plane Surface(28) = {26, 27};',
        'Transfinite Line{1, 3} = outx/grioutx + 1;',
        'Transfinite Line{2, 4} = outy/griouty + 1;',
        'Transfinite Line{13, 15} = inx/grix + 1;',
        'Transfinite Line{14, 16} = iny/griy + 1;']
    geo.add_raw_code(code)
    return geo


def p_item_tag(p):
    """item_tag : ITEM_TAG"""
    p[0] = ['ITEM_TAG', p[1]]


def as_sender_tuple(sender):
    """build a sender tuple

    >>> as_sender_tuple('joe@testco.com')
    ('joe@testco.com', 'joe@testco.com')

    >>> as_sender_tuple(('joe@testco.com', 'joe@testco.com'))
    ('joe@testco.com', 'joe@testco.com')

    >>> as_sender_tuple(['joe@testco.com', 'joe@testco.com'])
    ('joe@testco.com', 'joe@testco.com')
    """
    if isinstance(sender, str):
        return sender, sender
    return tuple(sender)


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 from_section(cls, section, **kwargs):
    """
        Creates the object from a section object.

        :param section: A section object containing at least the settings
                        specified by get_non_optional_settings()
        :param kwargs:  Additional keyword arguments
        """
    kwargs.update(cls.get_metadata().create_params_from_section(section))
    return cls(**kwargs)


def activate_transition(transition):
    """ Activates the specified :py:class:`ITransition`
        """


def read_snp_position_list(snp_list_file_path):
    """Read list of snp positions across all samples from the snplist.txt.

    Args:
        snp_list_file_path : path to snplist file to be written

    Returns:
        snp_list  : sorted list of tuple(str(CHROM), int(POS))
    """
    snp_list = list()
    with open(snp_list_file_path, 'r') as snp_list_file_object:
        for line in snp_list_file_object:
            chrom, pos = line.split()[0:2]
            snp_list.append((chrom, int(pos)))
    return snp_list


def backward(array, apointer, inputdata, output, source, spointer):
    """
    Move backward by one cell on tape. Equivalent to "<" in Brainfuck.
    """
    return array, apointer - 1, inputdata, output, source, spointer


@classmethod
def parse(cls, pattern):
    """
        Parse a formatted string representing a threshold optimization. E.g.
        'maximum recall @ precision >= 0.9' or
        'minimum match_rate @ recall >= 0.9'.

        :Parameters:
            pattern : `str`
                The optimization pattern to parse
        """
    match = cls.STRING_PATTERN.match(pattern.strip().lower())
    if match is None:
        raise ValueError('{0!r} does not match optimization pattern: '.
            format(pattern) + '"(maximum|minimum) <target> @ ' +
            '<cond> (>=|<=) [float]"')
    maximize, target, _, cond, _, greater, cond_value, _ = match.groups()
    return cls(maximize == 'maximum', target, cond, greater == '>=', float(
        cond_value))


def log(logcall, string, lock=None):
    """
    Report an information/warning/error/debug... message with a logger instance
    but taken into account a lock if given.

    :param logcall: call of the logger to perform.
    :type logcall: method
    :param string: string to pass by argument to the call.
    :type string: str
    :param lock: possible lock instance.
    :type lock: multiprocessing.Lock
    """
    if lock:
        lock.acquire()
        logcall(string)
        lock.release()
    else:
        logcall(string)


def _should_run_cmake(commands, cmake_with_sdist):
    """Return True if at least one command requiring ``cmake`` to run
    is found in ``commands``."""
    for expected_command in ['build', 'build_ext', 'develop', 'install',
        'install_lib', 'bdist', 'bdist_dumb', 'bdist_egg', 'bdist_rpm',
        'bdist_wininst', 'bdist_wheel', 'test']:
        if expected_command in commands:
            return True
    if 'sdist' in commands and cmake_with_sdist:
        return True
    return False


@classmethod
def get_BZ_integration_grid_shift_Y(cls, calc, **kwargs):
    """Return the shift of the Brillouin zone points along reciprocal lattice vector Y."""
    array = cls._get_BZ_integration_grid_shift(calc, **kwargs)
    if array is not None:
        return array[1]


def _check_callable(func, value):
    """Return true if func(value) returns is true or if *func* is
    *value*.
    """
    return value is func or func(value)


def can_paginate(operation_name=None):
    """
    Check if an operation can be paginated.

    :type operation_name: string
    :param operation_name: The operation name. This is the same name
            as the method name on the client. For example, if the
            method name is create_foo, and you'd normally invoke the
            operation as client.create_foo(**kwargs), if the
            create_foo operation can be paginated, you can use the
            call client.get_paginator('create_foo').

    """
    pass


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

        :param FileTransfersTransferViewType val:
        :rtype: EventType
        """
    return cls('file_transfers_transfer_view', val)


def _nval(val):
    """convert value to byte array"""
    if val < 0:
        raise ValueError
    buf = b''
    while val >> 7:
        m = val & 255 | 128
        buf += m.to_bytes(1, 'big')
        val >>= 7
    buf += val.to_bytes(1, 'big')
    return buf


def _show(a):
    """
    Prints the content of the array.
    :param a: The array to be shown
    """
    for i in range(len(a)):
        print(a[i])


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

        :param FileMemberActionError val:
        :rtype: FileMemberActionIndividualResult
        """
    return cls('member_error', val)


def within_footprint(img, wcsobj, x, y):
    """Determine whether input x, y fall in the science area of the image.

    Parameters
    ----------
    img : ndarray
        ndarray of image where non-science areas are marked with value of NaN.

    wcsobj : `~stwcs.wcsutil.HSTWCS`
        HSTWCS or WCS object with naxis terms defined.

    x, y : ndarray
        arrays of x, y positions for sources to be checked.

    Returns
    -------
    x, y : ndarray
        New arrays which have been trimmed of all sources that fall outside
        the science areas of the image

    """
    sky = wcsobj.pixel_to_world(x, y, 1)
    inmask = wcsobj.footprint_contains(sky)
    x = x[inmask]
    y = y[inmask]
    return x, y


def __to_float(val, digits):
    """Convert val into float with digits decimal."""
    try:
        return round(float(val), digits)
    except (ValueError, TypeError):
        return float(0)


@staticmethod
def _is_arr_like(val):
    """Returns true if SAM data is array-like. False if scalar."""
    if isinstance(val, (int, float, str)):
        return False
    else:
        try:
            len(val)
        except TypeError:
            return False
        else:
            return True


def arcsin(data=None, out=None, name=None, **kwargs):
    """Returns element-wise inverse sine of the input array.

    The input should be in the range `[-1, 1]`.
    The output is in the closed interval of [:math:`-\\pi/2`, :math:`\\pi/2`].

    .. math::
       arcsin([-1, -.707, 0, .707, 1]) = [-\\pi/2, -\\pi/4, 0, \\pi/4, \\pi/2]

    The storage type of ``arcsin`` output depends upon the input storage type:

       - arcsin(default) = default
       - arcsin(row_sparse) = row_sparse
       - arcsin(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_trig.cc:L187

    Parameters
    ----------
    data : NDArray
        The input array.

    out : NDArray, optional
        The output NDArray to hold the result.

    Returns
    -------
    out : NDArray or list of NDArrays
        The output of this function.
    """
    return 0,


def __call__(default):
    """ Return the value or the default if the object no longer
        has any value for the adaptation"""


def unload_fixture(apps, schema_editor):
    """Brutally deleting all entries for this model..."""
    Event = apps.get_model('eventsrouter', 'Event')
    Event.objects.all().delete()


def __call__(context, request, query=None):
    """
        The context provides a location that the vocabulary can make use of.
        The request provides a user that the vocabulary can personalize for.
        The query provides a filter the user has input so far.
        """


def unique(list_, key=lambda x: x):
    """efficient function to uniquify a list preserving item order"""
    seen = set()
    result = []
    for item in list_:
        seenkey = key(item)
        if seenkey in seen:
            continue
        seen.add(seenkey)
        result.append(item)
    return result


def zig_zag_decode(value):
    """Inverse of ZigZagEncode()."""
    if not value & 1:
        return value >> 1
    return value >> 1 ^ ~0


def no_instance_params(cls):
    """
    Disables instance parameters on the class
    """
    cls._disable_instance__params = True
    return cls


def patch_click() ->None:
    """Make Click not crash.

    On certain misconfigured environments, Python 3 selects the ASCII encoding as the
    default which restricts paths that it can access during the lifetime of the
    application.  Click refuses to work in this scenario by raising a RuntimeError.

    In case of Black the likelihood that non-ASCII characters are going to be used in
    file paths is minimal since it's Python source code.  Moreover, this crash was
    spurious on Python 3.7 thanks to PEP 538 and PEP 540.
    """
    try:
        from click import core
        from click import _unicodefun
    except ModuleNotFoundError:
        return
    for module in (core, _unicodefun):
        if hasattr(module, '_verify_python3_env'):
            module._verify_python3_env = lambda : None


@classmethod
def handlerFor(cls, base):
    """Returns the handler for a particular path"""
    return cls.paths[base]


def apply_error_style(w, error):
    """Applies error styling to the supplied widget based on the error code"""
    if error:
        color = '#FFCC00' if error == 'eval' else '#cc0000'
        w.layout.border = '5px solid %s' % color
    else:
        w.layout.border = '0px'