def json_schema_to_postgres_type(schema: dict) ->str:
    """
    Maps a JSON schema to a Postgres type for on the fly mapping.
    :param schema: JSON schema to map.
    """
    if schema['type'] == 'string':
        return 'TEXT'
    elif schema['type'] == 'integer':
        return 'INTEGER'
    elif schema['type'] == 'number':
        return 'DOUBLE PRECISION'
    elif schema['type'] == 'object':
        return 'JSON'
    elif schema['type'] == 'array':
        return 'JSON'
    elif schema['type'] == 'boolean':
        return 'BOOLEAN'
    else:
        return 'TEXT'


def f_computeVisibilityPeriodsWithPA(ephemeris, mjdmin, mjdmax, ra, dec, pa):
    """Returns two lists containing the start end end of each
    visibility period and a list containing a status flag

    flag = 0 visibility period fully in the search interval
    flag = -1 start of the visibility period truncated by
           the start of the search interval
    flag = -2 end of the visibility period truncated by
           the end of the search interval
    flag = +1 the search interval is fully included in
           the visibility period

    Parameters
    ----------
    ephemeris: Ephemeris
        The input ephemeris object.
    mjdmin: float
        The beginning of the search interval (modified
        Julian date). It must be covered by the ephemeris.
    mjdmax: float
        The end of the search interval (modified
        Julian date). It must be covered by the ephemeris.
    ra: float
        The input RA coordinate (equatorial coordinate, in rad).
    dec: float
        The input DEC coordinate (equatorial coordinate, in rad).
    pa: float
        The position angle.

    Example
    -------
    >>> f_computeVisibilityPeriodsWithPA(ephemeris, mjdmin, mjdmax, ra, dec,
    pa)

    Returns
    -------
    tuple
        The lists of visibility period starts and ends with flags
    """
    if ephemeris.amin > mjdmin:
        print(
            'f_computeVisibilityPeriodsWithPA(): the start of the search                 interval is not covered by the ephemeris.'
            )
        print(
            'Ephemeris start date (modified Julian date):                 {:8.5f}'
            .format(ephemeris.amin))
        print(
            'Search interval start date (modified Julian date):                 {:8.5f}'
            .format(mjdmin))
        raise ValueError
    if ephemeris.amax < mjdmax:
        print(
            'f_computeVisibilityPeriodsWithPA(): the end of the search                 interval is not covered by the ephemeris.'
            )
        print(
            'Ephemeris end date (modified Julian date):                 {:8.5f}'
            .format(ephemeris.amax))
        print(
            'Search interval end date (modified Julian date):                 {:8.5f}'
            .format(mjdmax))
        raise ValueError
    iflip = False
    wstart = mjdmin
    startList = []
    endList = []
    statusList = []
    scanningStepSize = 0.1
    span = int((mjdmax - mjdmin) / scanningStepSize)
    iflag_old = ephemeris.is_valid(mjdmin, ra, dec, pa)
    for i in range(span):
        currentdate = mjdmin + (i + 1) * scanningStepSize
        if currentdate >= mjdmax:
            currentdate = mjdmax
        iflag = ephemeris.is_valid(currentdate, ra, dec, pa)
        if iflag != iflag_old:
            if iflag:
                step = currentdate - scanningStepSize
                wstart = ephemeris.bisect_by_attitude(currentdate, step, ra,
                    dec, pa)
            else:
                step = currentdate - scanningStepSize
                wend = ephemeris.bisect_by_attitude(step, currentdate, ra,
                    dec, pa)
                startList.append(wstart)
                endList.append(wend)
                if iflip:
                    statusList.append(0)
                else:
                    statusList.append(-1)
            iflip = True
            iflag_old = iflag
    if iflag and iflip:
        startList.append(wstart)
        endList.append(currentdate)
        statusList.append(-2)
    if iflag and not iflip:
        startList.append(mjdmin)
        endList.append(mjdmax)
        statusList.append(1)
    return startList, endList, statusList


def _log_entries_to_log4j(entries):
    """Convert log entries from a single log file to log4j format, tracking
    line number.

    See :py:meth:`mrjob.logs.log4j._parse_hadoop_log4j_records`
    for format.
    """
    line_num = 0
    for entry in entries:
        message = entry.payload.get('message') or ''
        num_lines = len(message.split('\n'))
        yield dict(caller_location='', level=entry.severity or '', logger=
            entry.payload.get('class') or '', message=message, num_lines=
            num_lines, start_line=line_num, thread='', timestamp=entry.
            timestamp or '')
        line_num += num_lines


def _element_identification_string(element):
    """
    Gets a string that will hopefully help in identifing an element when there
    is an error.
    """
    info_string = 'tag: {}'.format(element.tag)
    try:
        elem_id = element.attrib['id']
        info_string += ' id: {}'.format(elem_id)
    except KeyError:
        pass
    return info_string


@staticmethod
def strategy_override(config, path, base, nxt):
    """ use nxt, and ignore base. """
    return nxt


def _is_float(s):
    """
    Check to see if a string value is a valid float.
    """
    try:
        float(s)
        return True
    except ValueError:
        return False


def get_events(phylo):
    """
    Infer gain/loss on individual branches of the tree.
    """
    phylo.disambiguate_labels()
    events = []
    event_nodes = phylo.get_event_nodes()
    for name in event_nodes:
        n = phylo.get_node(name)
        if n.ancestor.label == 1:
            events.extend(['loss_{}'.format(name)])
        else:
            events.extend(['gain_{}'.format(name)])
    orth_str = ','.join(events)
    return orth_str


def provider_parser(subparser):
    """Generate subparser for CloudXNS"""
    subparser.add_argument('--auth-username', help=
        'specify API-KEY for authentication')
    subparser.add_argument('--auth-token', help=
        'specify SECRET-KEY for authentication')


@staticmethod
def capability_proactively_reported():
    """Return True if the capability is proactively reported.

        Set properties_proactively_reported() for proactively reported properties.
        Applicable to DoorbellEventSource.
        """
    return None


def get_resource_filename(manager, resource_name):
    """Return a true filesystem path for `resource_name`

        `manager` must be an ``IResourceManager``"""


def _safe_strip(value):
    """Strips the value if it is not None.

    :param value: text to be cleaned up
    :type  value: str or None

    :return: clean value if one was specified; None otherwise
    :rtype: str or None
    """
    if value is not None:
        return value.strip()
    return None


def bmesh_to_mesh(bm: 'bmesh.types.BMesh', mesh: 'bpy.types.Mesh', object:
    'bpy.types.Object', skip_tessface: bool):
    """Converts a bmesh to a Mesh. This is reserved for exiting editmode.

    :param bm: The bmesh to operate on.
    :type bm: 'bmesh.types.BMesh'
    :param mesh: Undocumented.
    :type mesh: 'bpy.types.Mesh'
    :param object: Undocumented.
    :type object: 'bpy.types.Object'
    :param skip_tessface: don’t calculate mfaces
    :type skip_tessface: bool
    """
    pass


def swap():
    """Swap order of selected strips within tracks

    """
    pass


def roundup(n, k=64):
    """Round up to the next multiple of 64."""
    return k * ((n + k - 1) // k)


def c_add32(a, b):
    """
    Add *a* and *b* within the uint32 value range.

    >>> c_add32(0xFFFFFFFF, 1)
    0
    >>> c_add32(0xFFFFFFFF, 0xFFFFFFFF)
    4294967294
    """
    return a + b & 4294967295


def extract_number_from_string(text):
    """Take number like string out of text.
    """
    numberstr_list = list()
    chunks = list()
    for char in text:
        if char.isdigit() or char == '.':
            chunks.append(char)
        elif len(chunks):
            numberstr_list.append(''.join(chunks))
            chunks = list()
    if len(chunks):
        numberstr_list.append(''.join(chunks))
    new_numberstr_list = list()
    for s in numberstr_list:
        try:
            float(s)
            new_numberstr_list.append(s)
        except:
            pass
    return new_numberstr_list


def get_document_number(comments):
    """ Get the FR document number for the notice against which the comments
    are being submitted
    """
    return comments[0]['docId']


def google_text_emphasis(style):
    """return a list of all emphasis modifiers of the element"""
    emphasis = []
    if 'text-decoration' in style:
        emphasis.append(style['text-decoration'])
    if 'font-style' in style:
        emphasis.append(style['font-style'])
    if 'font-weight' in style:
        emphasis.append(style['font-weight'])
    return emphasis


@classmethod
def _extract_error_message(cls, e):
    """Extract error message for queries"""
    message = str(e)
    try:
        if isinstance(e.args, tuple) and len(e.args) > 1:
            message = e.args[1]
    except Exception:
        pass
    return message


def getphase(Tc, Pc, T, P, x, region):
    """Return fluid phase string name

    Parameters
    ----------
    Tc : float
        Critical temperature, [K]
    Pc : float
        Critical pressure, [MPa]
    T : float
        Temperature, [K]
    P : float
        Pressure, [MPa]
    x : float
        Quality, [-]
    region: int
        Region number, used only for IAPWS97 region definition

    Returns
    -------
    phase : str
        Phase name
    """
    P = round(P, 8)
    T = round(T, 8)
    if P > Pc and T > Tc:
        phase = 'Supercritical fluid'
    elif T > Tc:
        phase = 'Gas'
    elif P > Pc:
        phase = 'Compressible liquid'
    elif P == Pc and T == Tc:
        phase = 'Critical point'
    elif region == 4 and x == 1:
        phase = 'Saturated vapor'
    elif region == 4 and x == 0:
        phase = 'Saturated liquid'
    elif region == 4:
        phase = 'Two phases'
    elif x == 1:
        phase = 'Vapour'
    elif x == 0:
        phase = 'Liquid'
    return phase


def reset_db_parameter_group(DBParameterGroupName=None, ResetAllParameters=
    None, Parameters=None):
    """
    Modifies the parameters of a DB parameter group to the engine/system default value. To reset specific parameters, provide a list of the following: ParameterName and ApplyMethod . To reset the entire DB parameter group, specify the DBParameterGroup name and ResetAllParameters parameters. When resetting the entire group, dynamic parameters are updated immediately and static parameters are set to pending-reboot to take effect on the next DB instance restart or RebootDBInstance request.
    See also: AWS API Documentation

    Examples
    This example resets all parameters for the specified DB parameter group to their default values.
    Expected Output:

    :example: response = client.reset_db_parameter_group(
        DBParameterGroupName='string',
        ResetAllParameters=True|False,
        Parameters=[
            {
                'ParameterName': 'string',
                'ParameterValue': 'string',
                'Description': 'string',
                'Source': 'string',
                'ApplyType': 'string',
                'DataType': 'string',
                'AllowedValues': 'string',
                'IsModifiable': True|False,
                'MinimumEngineVersion': 'string',
                'ApplyMethod': 'immediate'|'pending-reboot'
            },
        ]
    )

    :type DBParameterGroupName: string
    :param DBParameterGroupName: [REQUIRED]
            The name of the DB parameter group.
            Constraints:
            Must be 1 to 255 alphanumeric characters
            First character must be a letter
            Cannot end with a hyphen or contain two consecutive hyphens

    :type ResetAllParameters: boolean
    :param ResetAllParameters: Specifies whether (true ) or not (false ) to reset all parameters in the DB parameter group to default values.
            Default: true

    :type Parameters: list
    :param Parameters: To reset the entire DB parameter group, specify the DBParameterGroup name and ResetAllParameters parameters. To reset specific parameters, provide a list of the following: ParameterName and ApplyMethod . A maximum of 20 parameters can be modified in a single request.
            MySQL
            Valid Values (for Apply method): immediate | pending-reboot
            You can use the immediate value with dynamic parameters only. You can use the pending-reboot value for both dynamic and static parameters, and changes are applied when DB instance reboots.
            MariaDB
            Valid Values (for Apply method): immediate | pending-reboot
            You can use the immediate value with dynamic parameters only. You can use the pending-reboot value for both dynamic and static parameters, and changes are applied when DB instance reboots.
            Oracle
            Valid Values (for Apply method): pending-reboot
            (dict) --This data type is used as a request parameter in the ModifyDBParameterGroup and ResetDBParameterGroup actions.
            This data type is used as a response element in the DescribeEngineDefaultParameters and DescribeDBParameters actions.
            ParameterName (string) --Specifies the name of the parameter.
            ParameterValue (string) --Specifies the value of the parameter.
            Description (string) --Provides a description of the parameter.
            Source (string) --Indicates the source of the parameter value.
            ApplyType (string) --Specifies the engine specific parameters type.
            DataType (string) --Specifies the valid data type for the parameter.
            AllowedValues (string) --Specifies the valid range of values for the parameter.
            IsModifiable (boolean) --Indicates whether (true ) or not (false ) the parameter can be modified. Some parameters have security or operational implications that prevent them from being changed.
            MinimumEngineVersion (string) --The earliest engine version to which the parameter can apply.
            ApplyMethod (string) --Indicates when to apply parameter updates.

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

    """
    pass


def quote_help(s: str) ->str:
    """Double percent signs, and quote newlines.
    This is needed in help for argparse.
    """
    return s.replace('%', '%%').replace('\n', '\\n')


def _add_as_gamma_to_case_statement(case_statement: str, gamma_col_name):
    """As the correct column alias to the case statement if it does not exist

    Args:
        case_statement (str): Original case statement

    Returns:
        str: case_statement with correct alias
    """
    sl = case_statement.lower()
    sl = sl.replace('\n', ' ').replace('\r', '')
    sl = sl.strip()
    if sl[-4:] != ' end':
        last_end_index = sl.rfind(' end ')
        sl = sl[:last_end_index + 5]
    return f'{sl} as gamma_{gamma_col_name}'


def rldecode(data):
    """
    RunLength decoder (Adobe version) implementation based on PDF Reference
    version 1.4 section 3.3.4:
        The RunLengthDecode filter decodes data that has been encoded in a
        simple byte-oriented format based on run length. The encoded data
        is a sequence of runs, where each run consists of a length byte
        followed by 1 to 128 bytes of data. If the length byte is in the
        range 0 to 127, the following length + 1 (1 to 128) bytes are
        copied literally during decompression. If length is in the range
        129 to 255, the following single byte is to be copied 257 - length
        (2 to 128) times during decompression. A length value of 128
        denotes EOD.
    """
    decoded = b''
    i = 0
    while i < len(data):
        length = data[i]
        if length == 128:
            break
        if length >= 0 and length < 128:
            for j in range(i + 1, i + 1 + (length + 1)):
                decoded += bytes((data[j],))
            i = i + 1 + (length + 1)
        if length > 128:
            run = bytes((data[i + 1],)) * (257 - length)
            decoded += run
            i = i + 1 + 1
    return decoded


@staticmethod
def get_fold_lvl(block):
    """
        Gets the block fold level

        :param block: block to access.
        :returns: The block fold level
        """
    if block is None:
        return 0
    state = block.userState()
    if state == -1:
        state = 0
    return (state & 67043328) >> 16


@classmethod
def get_type_name(cls):
    """Returns the class name unless the __type_name__ attribute is defined.
        """
    retval = cls.__type_name__
    if retval is None:
        retval = cls.__name__
    return retval


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


def isEncapsulated(interval1, interval2):
    """
    Is interval1 encapsulated by interval2?

    :param interval1:
    :param interval2:

    :return: True if interval1 is encapsulated by interval2 (including that they are equal).
    """
    if max(interval1.value) <= max(interval2.value) and min(interval1.value
        ) >= min(interval2.value):
        return True
    return False


def find_actual_position(ORI_gc, ORI_ta, TER_gc, TER_ta, gc_cum, ta_cum,
    positions):
    """
    Find position of ORI and TER - assumed to be before gene where predicted position is in
    and after the gene where the predicted position is in, respectively

    :param ORI_gc:      Predicted position of ORI using GC-skew
    :param ORI_ta:      Predicted position of ORI using TA-skew
    :param TER_gc:      Predicted position of TER using GC-skew
    :param TER_ta:      Predicted position of TER using TA-skew
    :param gc_cum:      List of cumulative GC-skews
    :param ta_cum:      List of cumulative TA-skews
    :param positions:   List of gene positions
    :return:            Actual position for ORI and TER using both GC and TA-skew,
                        and the indices values in the list (used later for plotting)
    """
    ori_gc_found = ter_gc_found = ori_ta_found = ter_ta_found = False
    """Loop through all genes, find the gene which contains the predicted position
    and set the new predicted position as the position before that gene (ORI) or after
    that gene (TER). Once all positions have been found, loop breaks."""
    for gene in positions:
        if not ori_gc_found:
            if positions[gene][0] <= ORI_gc <= positions[gene][1]:
                ORI_gc = positions[gene][0]
                ori_gc_found = True
        if not ter_gc_found:
            if positions[gene][0] <= TER_gc <= positions[gene][1]:
                TER_gc = positions[gene][1]
                ter_gc_found = True
        if not ori_ta_found:
            if positions[gene][0] <= ORI_ta <= positions[gene][1]:
                ORI_ta = positions[gene][0]
                ori_ta_found = True
        if not ter_ta_found:
            if positions[gene][0] <= TER_ta <= positions[gene][1]:
                TER_ta = positions[gene][1]
                ter_ta_found = True
        if ori_gc_found and ter_gc_found and ori_ta_found and ter_ta_found:
            break
    ORI_gc = ORI_gc - 1
    ORI_ta = ORI_ta - 1
    TER_gc = TER_gc - 1
    TER_ta = TER_ta - 1
    ORI_gc_val = gc_cum[ORI_gc]
    ORI_ta_val = ta_cum[ORI_ta]
    TER_gc_val = gc_cum[TER_gc]
    TER_ta_val = ta_cum[TER_ta]
    return (ORI_gc, ORI_gc_val, TER_gc, TER_gc_val, ORI_ta, ORI_ta_val,
        TER_ta, TER_ta_val)


def describe_pending_maintenance_actions(ResourceIdentifier=None, Filters=
    None, Marker=None, MaxRecords=None):
    """
    Returns a list of resources (for example, DB instances) that have at least one pending maintenance action.
    See also: AWS API Documentation

    Examples
    This example lists information for all pending maintenance actions for the specified DB instance.
    Expected Output:

    :example: response = client.describe_pending_maintenance_actions(
        ResourceIdentifier='string',
        Filters=[
            {
                'Name': 'string',
                'Values': [
                    'string',
                ]
            },
        ],
        Marker='string',
        MaxRecords=123
    )

    :type ResourceIdentifier: string
    :param ResourceIdentifier: The ARN of a resource to return pending maintenance actions for.

    :type Filters: list
    :param Filters: A filter that specifies one or more resources to return pending maintenance actions for.
            Supported filters:
            db-cluster-id - Accepts DB cluster identifiers and DB cluster Amazon Resource Names (ARNs). The results list will only include pending maintenance actions for the DB clusters identified by these ARNs.
            db-instance-id - Accepts DB instance identifiers and DB instance ARNs. The results list will only include pending maintenance actions for the DB instances identified by these ARNs.
            (dict) --This type is not currently supported.
            Name (string) -- [REQUIRED]This parameter is not currently supported.
            Values (list) -- [REQUIRED]This parameter is not currently supported.
            (string) --

    :type Marker: string
    :param Marker: An optional pagination token provided by a previous DescribePendingMaintenanceActions request. If this parameter is specified, the response includes only records beyond the marker, up to a number of records specified by MaxRecords .

    :type MaxRecords: integer
    :param MaxRecords: The maximum number of records to include in the response. If more records exist than the specified MaxRecords value, a pagination token called a marker is included in the response so that the remaining results can be retrieved.
            Default: 100
            Constraints: Minimum 20, maximum 100.

    :rtype: dict
    :return: {
        'PendingMaintenanceActions': [
            {
                'ResourceIdentifier': 'string',
                'PendingMaintenanceActionDetails': [
                    {
                        'Action': 'string',
                        'AutoAppliedAfterDate': datetime(2015, 1, 1),
                        'ForcedApplyDate': datetime(2015, 1, 1),
                        'OptInStatus': 'string',
                        'CurrentApplyDate': datetime(2015, 1, 1),
                        'Description': 'string'
                    },
                ]
            },
        ],
        'Marker': 'string'
    }

    """
    pass


def asyncproxy(proxy, asynchronous=True):
    """convenience method to set proxy to asynchronous or sync mode."""
    proxy._pyroAsync(asynchronous)


def union(a, b):
    """ return the union of two lists """
    return list(set(a) | set(b))


def _limit_es(expected_mb):
    """Protection against creating too small or too large chunks."""
    if expected_mb < 1:
        expected_mb = 1
    elif expected_mb > 10 ** 7:
        expected_mb = 10 ** 7
    return expected_mb


def get_file(url):
    """
        Should not be called because is_in_cache() always returns False
        """
    return None


def atomic_number(atom):
    """Get the atomic number for an atom.

    Parameters
    ----------
    atom : rdkit.Chem.rdchem.Atom
        RDKit atom instance.

    Returns
    -------
    list
       List containing one int only.
    """
    return [atom.GetAtomicNum()]


def p_function_body(p):
    """function_body : shell_command
                     | shell_command redirection_list"""
    assert p[1].kind == 'compound'
    p[0] = p[1]
    if len(p) == 3:
        p[0].redirects.extend(p[2])
        assert p[0].pos[0] < p[0].redirects[-1].pos[1]
        p[0].pos = p[0].pos[0], p[0].redirects[-1].pos[1]


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


@staticmethod
def get_identifier_field(facility):
    """
        Return name of the field used to extract template name when creating a
        template. This field is also used to store the identifier for
        instantiated templates
        """
    if facility == 'LCO':
        return 'name'
    raise NotImplementedError


@classmethod
def stop_recording_skipped(cls):
    """
        Stop collecting OptionErrors recorded with the
        record_skipped_option method and return them
        """
    if cls._errors_recorded is None:
        raise Exception('Cannot stop recording before it is started')
    recorded = cls._errors_recorded[:]
    cls._errors_recorded = None
    return recorded


def vector_sub(vector1, vector2):
    """
    Subtracts one vector to another
    :param vector1: list(float, float, float)
    :param vector2: list(float, float, float)
    :return: list(float, float, float)
    """
    return [vector1[0] - vector2[0], vector1[1] - vector2[1], vector1[2] -
        vector2[2]]


@classmethod
def on(cls, connection=None):
    """
        Begin querying the model on a given connection.

        :param connection: The connection name
        :type connection: str

        :return: A Builder instance
        :rtype: orator.orm.Builder
        """
    instance = cls()
    instance.set_connection(connection)
    return instance.new_query()


def decode_state(state_repr, no_spins, labels):
    """Decode integer representation of state into array +/- 1 array.

    :param state_repr: integer to be decoded
    :type state_repr: int
    :param no_bits: how many bits to decode. Note that this parameter is
     neccessary because the leading zeros matter.
    :type no_bits: int
    :returns: array of len `no_bits `consisting of -1 and 1
     respectively if corresponding bit was unset/set. Bits are taken in
     higher -> lower order, so for instance number (01101)b gets converted
     to [1, -1, 1, 1, -1].
    :rtype: :py:class:`numpy.ndarray`
    """
    state = {}
    for i in range(no_spins):
        state[labels[no_spins - (i + 1)]] = 1 if state_repr % 2 else -1
        state_repr //= 2
    return state


def separate_names(names):
    """
    Split a set of names for an option into configuration names,
    positional argument names, and optional argument names.

    An argument is optional if it starts with '-',
    configuration if it contains ':',
    and positional otherwise
    """
    configs = []
    args = []
    options = []
    for name in names:
        if name.startswith('-'):
            options.append(name)
        elif ':' in name:
            configs.append(name.split(':'))
        else:
            args.append(name)
    return configs, args, options


def add_query_kwargs(kwargs, visitor, constraints, index):
    """ Construct KeyConditionExpression and FilterExpression """
    query_const, filter_const = constraints.remove_index(index)
    kwargs['key_condition_expr'] = query_const.build(visitor)
    if filter_const:
        kwargs['filter'] = filter_const.build(visitor)
    if index.name != 'TABLE':
        kwargs['index'] = index.name


def _sign(x: int) ->int:
    """Get the sign of ``x``."""
    return int(abs(x) / x)


def get_name(value) ->str:
    """Return a best guess at the qualified name for a class or function.

    :param value: A class or function object.
    :type value: class or function
    :returns str:
    """
    if value.__module__ == '__builtin__':
        return value.__name__
    else:
        return '.'.join((value.__module__, value.__name__))


def percentage_to_float(x):
    """Convert a string representation of a percentage to float.

    >>> percentage_to_float('55%')
    0.55

    Args:
        x: String representation of a percentage

    Returns:
        float: Percentage in decimal form

    """
    return float(x.strip('%')) / 100


def _name(iris_obj, default='unknown'):
    """ Mimicks `iris_obj.name()` but with different name resolution order.

    Similar to iris_obj.name() method, but using iris_obj.var_name first to
    enable roundtripping.
    """
    return (iris_obj.var_name or iris_obj.standard_name or iris_obj.
        long_name or default)


def only_add_explain(info, level=4, **kwargs):
    """Includes the Python traceback before adding the generic
       information about a given exception and the likely cause.
    """
    result = ['']
    if level > 0:
        result.extend(info['simulated_python_traceback'])
    else:
        result.extend(info['python_traceback'])
    result.append('')
    if 'generic' in info:
        for line in info['generic'].split('\n'):
            result.append('    ' + line)
    if 'cause_header' in info:
        for line in info['cause_header'].split('\n'):
            result.append('    ' + line)
    if 'cause' in info:
        for line in info['cause'].split('\n'):
            result.append('        ' + line)
    return result


def yesno(value: bool, capitalize: bool=True) ->str:
    """Return "yes" or "no" as textual representation of Boolean value.
    Returned string is capitalized by default.

    :param value: value to be represented as `str`
    :type value: bool
    :param capitalize: whether to capitalize output string, defaults to True
    :type capitalize: bool, optional
    :return: textual representation of Boolean value
    :rtype: str
    """
    if value:
        ret = 'tak'
    else:
        ret = 'nie'
    if capitalize:
        return ret.capitalize()
    return ret


def _write_text(file, text):
    """ Write to file in utf-8 encoding."""
    with open(file, mode='w', encoding='utf-8') as f:
        return f.write(text)


@classmethod
def read_chunk(cls, opc_sync: bool, context: str) ->'IoTransferEventArgs':
    """Creates new IoTransferEventArgs of read string

		:param opc_sync: defines if the command is OPC-synchronised
		:param context: SCPI query. It is truncated to maximum of 100 characters.
		:return: IoTransferEventArgs object of a read string operation."""
    return cls(True, opc_sync, None, context)


def preset_add(name: str='', remove_name: bool=False, remove_active: bool=
    False, use_focal_length: bool=False):
    """Add or remove a Camera Preset

    :param name: Name, Name of the preset, used to make the path name
    :type name: str
    :param remove_name: remove_name
    :type remove_name: bool
    :param remove_active: remove_active
    :type remove_active: bool
    :param use_focal_length: Include Focal Length, Include focal length into the preset
    :type use_focal_length: bool
    """
    pass


def radius_set(radius: float=1.0):
    """Set per-point radius which is used for bevel tapering

    :param radius: Radius
    :type radius: float
    """
    pass


def get_notebook(current_scene_db, library_db, name):
    """gets a notebook path from name and library name"""
    from src.praxxis.notebook import notebook
    from src.praxxis.util import error
    from src.praxxis.sqlite import sqlite_notebook
    tmp_name = notebook.get_notebook_by_ordinal(current_scene_db, name)[0]
    if tmp_name is not None:
        name = tmp_name
    notebook_data = sqlite_notebook.get_notebook(library_db, name)
    if not len(notebook_data) == 1:
        notebook_data = [notebook.handle_duplicate_notebook(library_db,
            notebook_data, name)]
    return notebook_data[0]


def matrixFromGeometry(shifts, angles, inverseTransform):
    """ Create the transformation matrix from a given
    2D shifts in X and Y...and the 3 euler angles.
    """
    from pwem.convert.transformations import euler_matrix
    radAngles = -angles
    M = euler_matrix(radAngles[0], radAngles[1], radAngles[2], 'szyz')
    if inverseTransform:
        from numpy.linalg import inv
        M[:3, (3)] = -shifts[:3]
        M = inv(M)
    else:
        M[:3, (3)] = shifts[:3]
    return M


@classmethod
def bayes_llk_negative(cls, z):
    """used to calculate the log-likelihood of negative values: quadratic"""
    return cls.PREFACTOR * z * z


def missing_whitespace_after_import_keyword(logical_line):
    """Multiple imports in form from x import (a, b, c) should have space
    between import statement and parenthesised name list.

    Okay: from foo import (bar, baz)
    E275: from foo import(bar, baz)
    E275: from importable.module import(bar, baz)
    """
    line = logical_line
    indicator = ' import('
    if line.startswith('from '):
        found = line.find(indicator)
        if -1 < found:
            pos = found + len(indicator) - 1
            yield pos, 'E275 missing whitespace after keyword'


def mirror_ho_m(height_image, magnification):
    """Usage: Find height of object using magnification"""
    return height_image / magnification


@classmethod
def store_tenant_obj(cls, tenant_id, obj):
    """Store the tenant obj. """
    cls.serv_obj_dict[tenant_id] = obj


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

        :param HasTeamFileEventsValue val:
        :rtype: FeatureValue
        """
    return cls('has_team_file_events', val)


def null_pks(page, data):
    """
    Nullifies primary keys within all supplied fields.

    Arguments:
    page -- Page object.
    data -- Page object in dictionary format.

    Returns:
    N/A. Overwrites the argument.
    """
    data['id'] = None
    data['pk'] = None
    for field_name, field_val in data.items():
        if type(field_val) != list:
            continue
        for i, sub_item in enumerate(field_val):
            if 'pk' in sub_item:
                data[field_name][i]['pk'] = None


@classmethod
def get(cls, project_id):
    """
        Gets information about a project.

        Parameters
        ----------
        project_id : str
            The identifier of the project you want to load.

        Returns
        -------
        project : Project
            The queried project

        Examples
        --------
        .. code-block:: python

            import datarobot as dr
            p = dr.Project.get(project_id='54e639a18bd88f08078ca831')
            p.id
            >>>'54e639a18bd88f08078ca831'
            p.project_name
            >>>'Some project name'
        """
    path = '{}{}/'.format(cls._path, project_id)
    return cls.from_location(path, keep_attrs=[
        'advanced_options.default_monotonic_increasing_featurelist_id',
        'advanced_options.default_monotonic_decreasing_featurelist_id'])


def save_fig(fig, name):
    """Just store a figure."""
    fig.savefig(name)


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


def __repr__(A):
    """For `print` and `pprint`"""
    return A.to_str()


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


@staticmethod
def before_registration(cls):
    """Operations that should be performed to modify class attributes prior
        to registration. These actions will still be performed if the environment
        variable YGG_RUNNING_YGGSCHEMA is set."""
    pass


def zpl_bool(value):
    """
    Because ZPL encodes booleans as Y and N.
    """
    if value:
        return 'Y'
    else:
        return 'N'


def get_compact_git_history(repo, tag):
    """Gets all the commits between the tag and master

    :param repo: the repository that will be used to get the history
    :type repo: git.Repo
    :param tag: the tag that will be used as a base from where to get commits
    :type tag: str
    :return: whether the given repo's master branch is in sync with upstream
    :rtype: str
    """
    return repo.git.log('--oneline', '--graph', '{0}~1..master'.format(tag))


def close_all():
    """
    Closes every graph with :epkg:`matplotlib`.

    .. faqref::
        :tag: matplotlib
        :title: Plante après plusieurs graphes

        Il peut arriver que matplotlib fasse planter python sans qu'aucune exception ne soit générée.
        L'article `matplotlib crashing Python <http://stackoverflow.com/questions/26955017/matplotlib-crashing-python>`_
        suggère la solution suivante ::

            import matplotlib.pyplot as plt
            plt.close('all')

        Voir `close <http://matplotlib.org/api/pyplot_api.html?highlight=close#matplotlib.pyplot.close>`_.
    """
    import matplotlib.pyplot as plt
    plt.close('all')


def get_nb_minibatches(nb_samples, batch_size):
    """Compute the number of minibatches for keras.

    See [https://keras.io/models/sequential]
    """
    return nb_samples // batch_size + (1 if nb_samples % batch_size > 0 else 0)


def is_public_key_valid(key):
    """
    Check public key is valid.

    :param key: public key in HEX or bytes string format.
    :return: boolean.
    """
    if isinstance(key, str):
        key = bytes.fromhex(key)
    if len(key) < 33:
        return False
    elif key[0] == 4 and len(key) != 65:
        return False
    elif key[0] == 2 or key[0] == 3:
        if len(key) != 33:
            return False
    return True


def subtract_modulo(image1, image2):
    """Subtract two images, without clipping the result.

    .. code-block:: python

        out = ((image1 - image2) % MAX)

    :rtype: :py:class:`~PIL.Image.Image`
    """
    image1.load()
    image2.load()
    return image1._new(image1.im.chop_subtract_modulo(image2.im))


def p_expr(p):
    """ expr : macrocall
    """
    p[0] = str(p[1]()).strip()


def pytest_addoption(parser):
    """
    Configuration of pytest parsing
    """
    group = parser.getgroup('general')
    group.addoption('--seq-config', default=None, action='store', help=
        'Test file config')
    group.addoption('--sn', action='store', default='test', help=
        'Sample serial number or name')
    group.addoption('--wooqi', action='store_true', dest='wooqi tag', help=
        'wooqi tag to check if the test is runned thanks to wooqi')
    group = parser.getgroup('rerunfailures',
        're-run failing tests to eliminate flaky failures')
    group._addoption('--wooqi_reruns', action='store', dest='reruns', type=
        'int', default=0, help=
        'number of times to re-run failed tests. defaults to 0.')
    group = parser.getgroup('general')
    group.addoption('--wooqi_spec', action='store_true', dest='spec', help=
        'Print test result in specification format')
    parser.addini('spec_header_format', default='{path}::{class_name}',
        help='The format of the test headers when using the spec plugin')
    parser.addini('spec_test_format', default='[{result}]  {name}', help=
        'The format of the test results when using the spec plugin')


def set_position(parent, tree, remaining_nodes, delta_x, y_coordinate, pos):
    """Helper method to calculate the absolute position of nodes."""
    child = tree[parent]
    parent_node_x = pos[parent][0]
    if child is not None:
        child_x = parent_node_x + delta_x[child]
        pos[child] = child_x, y_coordinate[child]
        remaining_nodes.append(child)


def break_up_lines(text, max_line_width=80):
    """Break up the text in the given string so no line is longer than
    `max_line_width`. Any existing line endings are left unchanged.

    If any containing word is longer than this line width, then it will
    be broken up in order to meet the line width restrictions. A "word"
    means any consecutive string of characters not separated by whitespace.

    @param text {str} The string in which to break up words.
    @param max_line_width {int} The maximum line width allowed. Default is 80.
    """
    import textwrap
    lines = []
    for line in text.split('\n'):
        if not line:
            lines.append(line)
        else:
            lines += textwrap.wrap(line, max_line_width)
    return '\n'.join(lines)


def GetNextConsensus(header):
    """

    gets the address where the next consensus will occur

    """
    pass


@classmethod
def __list_fields(cls):
    """
        Get all the fields defined for our class, if we have an Index, try
        looking at the index mappings as well, mark the fields from Index as
        optional.
        """
    for name in cls._doc_type.mapping:
        field = cls._doc_type.mapping[name]
        yield name, field, False
    if hasattr(cls.__class__, '_index'):
        if not cls._index._mapping:
            return
        for name in cls._index._mapping:
            if name in cls._doc_type.mapping:
                continue
            field = cls._index._mapping[name]
            yield name, field, True


def get_local_type(xmltype):
    """
        Simplifies types names, e.g. XMLInteger is
        presented as int.

        This is used for nice printing only.
    """
    if xmltype == 'XMLBoolean':
        return 'bool'
    elif xmltype == 'XMLDecimal':
        return 'decimal'
    elif xmltype == 'XMLInteger':
        return 'int'
    elif xmltype == 'XMLDouble':
        return 'float'
    elif xmltype == 'XMLString':
        return 'str'
    elif xmltype == 'XMLDate':
        return 'date'
    elif xmltype == 'XMLDateTime':
        return 'datetime'
    else:
        return xmltype


def p_argumentlist_list(p):
    """argumentlist : argumentlist argument"""
    p[0] = p[1]
    p[0].append(p[2])


def _convert(type: str, date: str) ->int:
    """Convert dates to int representations."""
    res = None
    if type == 'month':
        res = int(date.format('YYYYMM'))
    elif type == 'day':
        res = int(date.format('YYYYMMDD'))
    elif type == 'hour':
        res = int(date.format('YYYYMMDDHH'))
    return res


def ticker_check(df):
    """
    Validates that Ticker Column is in the right format
    :param df: df['Ticker']
    :return: len(df),dfContents
    """


def next_power_of_2(x):
    """
    Returns the first power of two >= x, so f(2) = 2, f(127) = 128, f(65530) = 65536

    :param x:
    :return:
    """
    return 1 << (x - 1).bit_length()


@classmethod
def create_router_interface(cls, router_id, subnet_id):
    """Wrapper utility that returns a router interface."""
    interface = cls.routers_client.add_router_interface(router_id,
        subnet_id=subnet_id)
    return interface


def write_full_connect_layer(model_name='sas', layer_name='fullconnect',
    nrof_neurons='-1', nobias='true', activation='identity', type=
    'fullconnect', dropout='0', src_layer='none', ctc_loss=False):
    """
    Generate Python code defining a SAS deep learning fully connected layer

    Parameters
    ----------
    model_name : string, optional
       Name for deep learning model
    layer_name : string, optional
       Layer name
    nrof_neurons : string, optional
       number of output neurons
    nobias : string, optional
       omit (True) or retain (False) the bias term
    activation : string, optional
       activation function
    type : string, optional
       fully connected layer type (fullconnect or output)
    dropout : string, optional
       dropout factor (0 < dropout < 1.0)
    src_layer : string, optional
       source layer(s) for the convolution layer
    ctc_loss : boolean, optional
       specifies whether the CTC loss function is used for
       an output layer

    Returns
    -------
    string

    """
    if type == 'fullconnect':
        out = ['   s.addLayer(model=' + repr(model_name) + ', name=' + repr
            (layer_name) + ',', '              layer=dict(type=' + repr(
            type) + ', n=' + nrof_neurons + ',',
            '                         nobias=' + nobias + ', act=' + repr(
            activation) + ', dropout=' + dropout + '),',
            '              srcLayers=' + src_layer + ')']
    else:
        if ctc_loss:
            loss_error = 'CTC'
        else:
            loss_error = 'AUTO'
        out = ['   s.addLayer(model=' + repr(model_name) + ', name=' + repr
            (layer_name) + ',', '              layer=dict(type=' + repr(
            type) + ', n=' + nrof_neurons + ',',
            '                         nobias=' + nobias + ', act=' + repr(
            activation) + ',', '                         error = "' +
            loss_error + '"),', '              srcLayers=' + src_layer + ')']
    return '\n'.join(out)


def nextpow2(x):
    """ Return the smallest integral power of 2 that >= x """
    n = 2
    while n < x:
        n = 2 * n
    return n


def splitIgnoringQuotes(string, charToSplitOn=' '):
    """
        will split on charToSplitOn, ignoring things that are in quotes
    """
    string = string.lstrip()
    toReturn = []
    thisWord = []
    lastSplitPos = 0
    inQuote = False
    for char in string:
        if inQuote:
            if char == '"':
                inQuote = False
            else:
                thisWord.append(char)
        elif char == '"':
            inQuote = True
        elif char == charToSplitOn:
            toReturn.append(''.join(thisWord))
            thisWord = []
        else:
            thisWord.append(char)
    if len(thisWord) > 0:
        toReturn.append(''.join(thisWord))
    print('Parsed arguments:', toReturn)
    return toReturn


def job_assign_filter(instance, field, old_value, new_value):
    """
    A custom setter for the JobState.job.

    .. warning::
        This setter should not exist. job attribute should be read-only. This
        is a temporary kludge to get session restoring over DBus working. Once
        a solution that doesn't involve setting a JobState's job attribute is
        implemented, please remove this awful method.
    """
    return new_value


def add_to_fv(expr, FV, e2fi):
    """Add expression expr to factor vector FV and expr->FVindex mapping e2fi."""
    fi = e2fi.get(expr)
    if fi is None:
        fi = len(e2fi)
        FV.append(expr)
        e2fi[expr] = fi
    return fi


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

        :param RelocationBatchError val:
        :rtype: RelocationBatchJobStatus
        """
    return cls('failed', val)


def scal(v1, v2):
    """Yields the scalar product of `v1` and `v2`."""
    a1, b1, c1 = v1
    a2, b2, c2 = v2
    result = a1 * a2 + b1 * b2 + c1 * c2
    return float(result)


def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]


@classmethod
def parse_login(cls, res_js):
    """Parse login javascript response."""
    window = cls.exec_js(res_js)
    return {'code': window.code, 'redirect_uri': window.redirect_uri,
        'userAvatar': window.userAvatar}


def _array_feature_extrator(data, indices):
    """
    Implementation of operator *ArrayFeatureExtractor*
    with :epkg:`numpy`.
    """
    if len(indices.shape) == 2 and indices.shape[0] == 1:
        index = indices.ravel().tolist()
        add = len(index)
    elif len(indices.shape) == 1:
        index = indices.tolist()
        add = len(index)
    else:
        add = 1
        for s in indices.shape:
            add *= s
        index = indices.ravel().tolist()
    if len(data.shape) == 1:
        new_shape = 1, add
    else:
        new_shape = list(data.shape[:-1]) + [add]
    tem = data[..., index]
    res = tem.reshape(new_shape)
    return res


def __iter__():
    """Return an iterator for the keys of the mapping object.
        """


def remove_dep_from_items(items, dep):
    """
    Removes the given item id (dep) from the temporary list of
    dependencies of all items in the given list.
    """
    for item in items:
        try:
            item._deps.remove(dep)
        except ValueError:
            pass
    return items


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

        :param GenericErrorTag val:
        :rtype: GetMetadataErrorTagUnion
        """
    return cls('generic_error', val)


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 _get_attachment_id(node, volume):
    """Return the attachment ID for a node to a volume.

    :param node: The object representing the node.
    :param volume: The object representing the volume from cinder.

    :returns: The UUID of the attachment in cinder, if present. Otherwise
        returns None.
    """
    attachments = volume.attachments
    if attachments is None:
        return
    for attachment in attachments:
        if attachment.get('server_id') in (node.instance_uuid, node.uuid):
            return attachment.get('attachment_id')


def bytesize(size):
    """
    Returns a formatted version of a ``size`` given in bytes.
    """
    if size > 1073741824:
        return str(0.1 * int(10 * (float(size) / 1073741824))) + ' GB'
    elif size > 1048576:
        return str(0.1 * int(10 * (float(size) / 1048576))) + ' MB'
    elif size > 1024:
        return str(0.1 * int(10 * (float(size) / 1024))) + ' KB'
    else:
        return str(size) + 'B'


@staticmethod
def _start_repl(api):
    """
        Starts the REPL.
        """
    banner = (
        """IOTA API client for {uri} ({testnet}) initialized as variable `api`.
Type `help(api)` for list of API commands."""
        .format(testnet='testnet' if api.testnet else 'mainnet', uri=api.
        adapter.get_uri()))
    scope_vars = {'api': api}
    try:
        import IPython
    except ImportError:
        from code import InteractiveConsole
        InteractiveConsole(locals=scope_vars).interact(banner, '')
    else:
        print(banner)
        IPython.start_ipython(argv=[], user_ns=scope_vars)


def column_formatter(items_count, columns):
    """ Generator yelding indices up to `items_count` in a way
        like *nix shells columnize lists
    """
    rows = int(items_count / columns) + int(bool(items_count % columns))
    for row in range(0, rows):
        for idx in range(row, items_count, rows):
            yield idx
        yield -1


def start_transition(obj, *args, **kwargs):
    """Starts a state transition given some event."""
    from .models import System
    return System.get(obj).start_transition(*args, **kwargs)


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

        :param ShowcaseFileDownloadType val:
        :rtype: EventType
        """
    return cls('showcase_file_download', val)


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 get_schema():
    """Schema structure of this resource

    :return: schema dictionary
    :rtype: dict
    """
    return {'schema': {'schema_version': {'type': 'integer', 'default': 1},
        'host': {'schema_version': 1, 'title': 'Host', 'comment':
        'The host concerned by the acknowledge.', 'type': 'objectid',
        'data_relation': {'resource': 'host', 'embeddable': True},
        'required': True}, 'service': {'schema_version': 1, 'title':
        'Service', 'comment': 'The service concerned by the acknowledge.',
        'type': 'objectid', 'data_relation': {'resource': 'service',
        'embeddable': True}, 'required': True, 'nullable': True}, 'user': {
        'schema_version': 1, 'title': 'User', 'comment':
        'The user concerned by the acknowledge.', 'type': 'objectid',
        'data_relation': {'resource': 'user', 'embeddable': True},
        'required': True}, 'comment': {'schema_version': 1, 'title':
        'Comment', 'comment':
        'The comment of the acknowledge action. Free text.', 'type':
        'string', 'default': ''}, 'processed': {'schema_version': 1,
        'title': 'Processed', 'comment':
        'The action has been set on the host/service by Alignak and it can be considered as effective if processed is True'
        , 'type': 'boolean', 'default': False}, '_realm': {'schema_version':
        1, 'title': 'Realm', 'comment':
        'Realm this element belongs to. Note that this property will always be forced to the value of the concerned host realm.'
        , 'type': 'objectid', 'data_relation': {'resource': 'realm',
        'embeddable': True}}, '_sub_realm': {'schema_version': 1, 'title':
        'Sub-realms', 'comment':
        'Is this element visible in the sub-realms of its realm?', 'type':
        'boolean', 'default': True}, '_users_read': {'schema_version': 1,
        'type': 'list', 'schema': {'type': 'objectid', 'data_relation': {
        'resource': 'user', 'embeddable': True}}}}, 'schema_deleted': {}}


def ingredients(count):
    """Prints ingredients for making `count` arepas."""
    print('{:.2} cups arepa flour'.format(0.1 * count))
    print('{:.2} cups cheese'.format(0.1 * count))
    print('{:.2} cups water'.format(0.025 * count))


def filter_products(queryset, user):
    """
    No Restrictions.
    """
    return queryset


@classmethod
def _fill_single_double_repeats(cls, measures):
    """Replaces one- and two-measure repeat symbols with the appropriate chords
        :param measures: A list of measures (as strings)
        :return: A list of measures with filled repeats
        """
    for i in range(1, len(measures)):
        if measures[i] == 'x':
            measures[i] = cls._remove_markers(measures[i - 1])
    for i in range(2, len(measures) - 1):
        if measures[i] == 'r':
            measures[i] = cls._remove_markers(measures[i - 2])
            measures[i + 1] = cls._remove_markers(measures[i - 1])
    return measures


def autocast(action, action_space, ability_id):
    """Toggle autocast."""
    del action_space
    action.action_ui.toggle_autocast.ability_id = ability_id


def unescape(text):
    """
    Do reverse escaping.
    """
    escape_map = [('&', '&'), ('<', '<'), ('>', '>'), ('"',
        '"'), (''', "'")]
    for escape_values in escape_map:
        text = text.replace(*escape_values)
    return text


@classmethod
def get_table_names(cls, schema, inspector):
    """Need to consider foreign tables for PostgreSQL"""
    tables = inspector.get_table_names(schema)
    tables.extend(inspector.get_foreign_table_names(schema))
    return sorted(tables)


def nptype(dtype):
    """ converts to numpy types

    :param dtype: h5 writer type type
    :type dtype: :obj:`str`
    :returns: nupy type
    :rtype: :obj:`str`
    """
    if str(dtype) in ['string', b'string']:
        return 'str'
    return dtype


def writeClustal(filename, msa):
    """A simple writer for CLUSTAL format alignments.

    This lacks the characters showing degree of conservation
    but otherwise conforms to the CLUSTAL format standards."""
    msafile = open(filename, 'w')
    msafile.write('CLUSTALW file written by ProDy\n\n')
    for j in range(msa.numResidues() / 60):
        for i in range(msa.numSequences()):
            sequence = str(msa[i])
            msafile.write(msa.getLabel(i) + ' ' * (16 - len(msa.getLabel(i))))
            msafile.write(sequence[j * 60:(j + 1) * 60])
            msafile.write('\n')
        msafile.write('\n\n')
    for i in range(msa.numSequences()):
        sequence = str(msa[i])
        msafile.write(msa.getLabel(i) + ' ' * (16 - len(msa.getLabel(i))))
        msafile.write(sequence[(j + 1) * 60:])
        msafile.write('\n')
    msafile.close()
    return


def function_with_disk_stuff():
    """A sample function that might take a long time to test."""
    return False


def trace2index_flat(shape, ntrace):
    """
    Calculate the index of a trace assuming a flat structure
    """
    q = ntrace
    index = []
    for s in shape[:0:-1]:
        q, r = divmod(q, s)
        index.insert(0, r)
    index.insert(0, q)
    return tuple(index)


def dgl_graph_compact(*graph_data, **kwargs):
    """This operator compacts a CSR matrix generated by
    dgl_csr_neighbor_uniform_sample and dgl_csr_neighbor_non_uniform_sample.
    The CSR matrices generated by these two operators may have many empty
    rows at the end and many empty columns. This operator removes these
    empty rows and empty columns.

    Example:

       .. code:: python

      shape = (5, 5)
      data_np = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20], dtype=np.int64)
      indices_np = np.array([1,2,3,4,0,2,3,4,0,1,3,4,0,1,2,4,0,1,2,3], dtype=np.int64)
      indptr_np = np.array([0,4,8,12,16,20], dtype=np.int64)
      a = mx.nd.sparse.csr_matrix((data_np, indices_np, indptr_np), shape=shape)
      seed = mx.nd.array([0,1,2,3,4], dtype=np.int64)
      out = mx.nd.contrib.dgl_csr_neighbor_uniform_sample(a, seed, num_args=2, num_hops=1,
              num_neighbor=2, max_num_vertices=6)
      subg_v = out[0]
      subg = out[1]
      compact = mx.nd.contrib.dgl_graph_compact(subg, subg_v,
              graph_sizes=(subg_v[-1].asnumpy()[0]), return_mapping=False)

      compact.asnumpy()
      array([[0, 0, 0, 1, 0],
             [2, 0, 3, 0, 0],
             [0, 4, 0, 0, 5],
             [0, 6, 0, 0, 7],
             [8, 9, 0, 0, 0]])

    Defined in src/operator/contrib/dgl_graph.cc:L1582

    Parameters
    ----------
    graph_data : NDArray[]
        Input graphs and input vertex Ids.
    return_mapping : boolean, required
        Return mapping of vid and eid between the subgraph and the parent graph.
    graph_sizes : tuple of <long>, required
        the number of vertices in each graph.

    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 prefix_replace(original, old, new):
    """
    Replaces the old prefix of the original string by a new suffix
    :param original: string
    :param old: string
    :param new: string
    :return: string
    """
    return new + original[len(old):]


def _get_reporoot():
    """Returns the absolute path to the repo root directory on the current
    system.
    """
    from os import path
    import gblearn
    gblpath = path.abspath(gblearn.__file__)
    return path.dirname(path.dirname(gblpath))


def repr_message(msg):
    """
    用于 Message 和 SentMessage 对象的 __repr__ 和 __unicode__
    """
    from ..api.chats import Group
    text = str(msg.text or '').replace('\n', ' ↩ ')
    text += ' ' if text else ''
    if msg.sender == msg.bot.self:
        ret = '↪ {self.receiver.name}'
    elif isinstance(msg.chat, Group) and msg.member != msg.receiver:
        ret = '{self.sender.name} › {self.member.name}'
    else:
        ret = '{self.sender.name}'
    ret += ' : {text}({self.type})'
    return ret.format(self=msg, text=text)


def _set_kdf_iter(db_handle, kdf_iter=4000):
    """
    Set the number of iterations for the key derivation function.

    SQLCipher uses PBKDF2 key derivation to strengthen the key and make it
    resistent to brute force and dictionary attacks. The default
    configuration uses 4000 PBKDF2 iterations (effectively 16,000 SHA1
    operations). PRAGMA kdf_iter can be used to increase or decrease the
    number of iterations used.

    Implementation Notes:

    * PRAGMA kdf_iter must be called after PRAGMA key and before the first
        actual database operation or it will have no effect.

    * If a non-default value is used PRAGMA kdf_iter to create a database,
        it must also be called every time that database is opened.

    * It is not recommended to reduce the number of iterations if a
        passphrase is in use.

    :param db_handle: A handle to the SQLCipher database.
    :type db_handle: pysqlcipher.Connection
    :param kdf_iter: The number of iterations to use.
    :type kdf_iter: int
    """
    db_handle.cursor().execute("PRAGMA kdf_iter = '%d'" % kdf_iter)


@classmethod
def _name(cls):
    """Helper to get the class name once it's been created"""
    return cls.__name__


def quote_join(values):
    """Join a set of strings, presumed to be file paths, surrounded by quotes, for CMake"""
    surrounded = []
    for value in values:
        surrounded.append('"' + value + '"')
    return ' '.join(surrounded)


def spawnProcess(processProtocol, executable, args=(), env={}, path=None,
    uid=None, gid=None, usePTY=0, childFDs=None):
    """
        Spawn a process, with a process protocol.

        @type processProtocol: L{IProcessProtocol} provider
        @param processProtocol: An object which will be notified of all
            events related to the created process.

        @param executable: the file name to spawn - the full path should be
                           used.

        @param args: the command line arguments to pass to the process; a
                     sequence of strings. The first string should be the
                     executable's name.

        @type env: a C{dict} mapping C{str} to C{str}, or C{None}.
        @param env: the environment variables to pass to the child process. The
                    resulting behavior varies between platforms. If
                      - C{env} is not set:
                        - On POSIX: pass an empty environment.
                        - On Windows: pass C{os.environ}.
                      - C{env} is C{None}:
                        - On POSIX: pass C{os.environ}.
                        - On Windows: pass C{os.environ}.
                      - C{env} is a C{dict}:
                        - On POSIX: pass the key/value pairs in C{env} as the
                          complete environment.
                        - On Windows: update C{os.environ} with the key/value
                          pairs in the C{dict} before passing it. As a
                          consequence of U{bug #1640
                          <http://twistedmatrix.com/trac/ticket/1640>}, passing
                          keys with empty values in an effort to unset
                          environment variables I{won't} unset them.

        @param path: the path to run the subprocess in - defaults to the
                     current directory.

        @param uid: user ID to run the subprocess as. (Only available on
                    POSIX systems.)

        @param gid: group ID to run the subprocess as. (Only available on
                    POSIX systems.)

        @param usePTY: if true, run this process in a pseudo-terminal.
                       optionally a tuple of C{(masterfd, slavefd, ttyname)},
                       in which case use those file descriptors.
                       (Not available on all systems.)

        @param childFDs: A dictionary mapping file descriptors in the new child
                         process to an integer or to the string 'r' or 'w'.

                         If the value is an integer, it specifies a file
                         descriptor in the parent process which will be mapped
                         to a file descriptor (specified by the key) in the
                         child process.  This is useful for things like inetd
                         and shell-like file redirection.

                         If it is the string 'r', a pipe will be created and
                         attached to the child at that file descriptor: the
                         child will be able to write to that file descriptor
                         and the parent will receive read notification via the
                         L{IProcessProtocol.childDataReceived} callback.  This
                         is useful for the child's stdout and stderr.

                         If it is the string 'w', similar setup to the previous
                         case will occur, with the pipe being readable by the
                         child instead of writeable.  The parent process can
                         write to that file descriptor using
                         L{IProcessTransport.writeToChild}.  This is useful for
                         the child's stdin.

                         If childFDs is not passed, the default behaviour is to
                         use a mapping that opens the usual stdin/stdout/stderr
                         pipes.

        @see: L{twisted.internet.protocol.ProcessProtocol}

        @return: An object which provides L{IProcessTransport}.

        @raise OSError: Raised with errno C{EAGAIN} or C{ENOMEM} if there are
                        insufficient system resources to create a new process.
        """


def _plus(lhs=None, rhs=None, out=None, name=None, **kwargs):
    """Adds arguments element-wise.

    The storage type of ``elemwise_add`` output depends on storage types of inputs

       - elemwise_add(row_sparse, row_sparse) = row_sparse
       - elemwise_add(csr, csr) = csr
       - elemwise_add(default, csr) = default
       - elemwise_add(csr, default) = default
       - elemwise_add(default, rsp) = default
       - elemwise_add(rsp, default) = default
       - otherwise, ``elemwise_add`` generates output with default storage

    Parameters
    ----------
    lhs : NDArray
        first input
    rhs : NDArray
        second input

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

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


@classmethod
def start_task(cls, task_tag, skip_unresolved=False):
    """ Start task from registry

		:param task_tag: same as in :meth:`.WTaskDependencyRegistryStorage.start_task` method
		:param skip_unresolved: same as in :meth:`.WTaskDependencyRegistryStorage.start_task` method
		:return: None
		"""
    registry = cls.registry_storage()
    registry.start_task(task_tag, skip_unresolved=skip_unresolved)


@classmethod
def order_and_label(cls, t):
    """Order and label of a discrete type.

        Cf. :meth:`Profile.order_and_label`.

        Examples
        --------
            >>> ProfileHistogram.order_and_label(('abc', (0.1, 0.5, 0.4)))
            ('abc', '$r(abc)$')
            >>> ProfileHistogram.order_and_label('a~b>c')
            ('a~b>c', '$r(a\\\\sim b>c)$')
        """
    if isinstance(t, tuple):
        return t[0], '$r(%s)$' % t[0]
    else:
        return cls.order_and_label_weak(t)


def subprocess_setup():
    """
    Python installs a SIGPIPE handler by default. This is usually not what
    non-Python subprocesses expect
    """
    import signal
    signal.signal(signal.SIGPIPE, signal.SIG_DFL)


def get_header_value(header_list, key):
    """Filter the header_list with provided key value.

    This method is used to parse through the header list obtained from the
    SMAPI response header object and retrieve list of specific tuple objects
    with keys like Location, RequestId etc if present.

    :param header_list: The list of response headers returned from Alexa
        SKill Management API calls.
    :type: List[Tuple[str, str]]
    :param key: The field value which needs to be retrieved.
    :type: str
    :return: Returns the list field values if present, since there maybe
        multiple tuples with same key values.
    :rtype: List[Union[None,str]]
    """
    header_value = []
    if not header_list or key is None:
        return header_value
    return list(map(lambda x: x[1], filter(lambda x: x[0] == key, header_list))
        )


def is_aware(value):
    """
    Determines if a given datetime.datetime is aware.

    The logic is described in Python's docs:
    http://docs.python.org/library/datetime.html#datetime.tzinfo
    """
    return value.tzinfo is not None and value.tzinfo.utcoffset(value
        ) is not None


def find(function, iterable):
    """ Returns the first item in the list for which function(item) is True, None otherwise.
    """
    for x in iterable:
        if function(x) is True:
            return x


def _truncate_seq_pair(tokens_a, tokens_b, max_length):
    """Truncates a sequence pair in place to the maximum length."""
    while True:
        total_length = len(tokens_a) + len(tokens_b)
        if total_length <= max_length:
            break
        if len(tokens_a) > len(tokens_b):
            tokens_a.pop()
        else:
            tokens_b.pop()


def search(request_handler=u'/select', query=u'*:*', filters=None, start=0,
    rows=1000, sort=None, **params):
    """Perform a search with the given querystring and extra parameters"""


def get_service_type(f):
    """Retrieves service type from function."""
    return getattr(f, 'service_type', None)


def set_axlims(ax, lims, axname):
    """
    Set the data limits for the axis ax.

    Args:
        lims: tuple(2) for (left, right), tuple(1) or scalar for left only.
        axname: "x" for x-axis, "y" for y-axis.

    Return: (left, right)
    """
    left, right = None, None
    if lims is None:
        return left, right
    len_lims = None
    try:
        len_lims = len(lims)
    except TypeError:
        left = float(lims)
    if len_lims is not None:
        if len(lims) == 2:
            left, right = lims[0], lims[1]
        elif len(lims) == 1:
            left = lims[0]
    set_lim = getattr(ax, {'x': 'set_xlim', 'y': 'set_ylim'}[axname])
    if left != right:
        set_lim(left, right)
    return left, right


def flatten(iterables):
    """ Flatten an iterable, except for string elements. """
    for it in iterables:
        if isinstance(it, str):
            yield it
        else:
            for element in it:
                yield element


def adjust_learning_rate(optimizer, init_lr, epoch):
    """Sets the learning rate to the initial LR decayed by 10 every 30 epochs"""
    lr = init_lr * 0.1 ** (epoch // 30)
    for param_group in optimizer.param_groups:
        param_group['lr'] = lr


def eval_number(number):
    """
	Evaluate a numerical expressions in different string formats indicating
	base.

	:param str number: The string to evaluate.
	:return: The converted value.
	:rtype: int
	"""
    if number.startswith('0b'):
        return int(number[2:], 2)
    elif number.startswith('0x'):
        return int(number[2:], 16)
    elif number.startswith('0'):
        return int(number, 8)
    elif number.isdigit():
        return int(number)
    else:
        raise ValueError("unknown numerical value: '" + number + "'")


@classmethod
def _process_conditions(cls, raw_conditions):
    """Override in inheritors to format/modify any conditions."""
    return raw_conditions


def is_root_organization(obj):
    """
    Check whether this object(organization) is the root organization
    This check is performed based on whether this org's parent org is None
    According to current design, only root organization's parent org could
    not None
    :param obj: object to check
    :return: True if it's root organization, otherwise false
    """
    return obj is not None and obj.parent is None


def is_number(x):
    """Return whether `x` is a number."""
    try:
        x + 1
    except Exception:
        return False
    else:
        return True


def build_instance(Model, data, db):
    """
    Build a model instance.

    If the model instance doesn't have a primary key and the model supports
    natural keys, try to retrieve it from the database.
    """
    obj = Model(**data)
    if obj.pk is None and hasattr(Model, 'natural_key') and hasattr(Model.
        _default_manager, 'get_by_natural_key'):
        natural_key = obj.natural_key()
        try:
            obj.pk = Model._default_manager.db_manager(db).get_by_natural_key(*
                natural_key).pk
        except Model.DoesNotExist:
            pass
    return obj


def __deserialize_date(B, string):
    """Deserializes string to date.

        :param string: str.
        :return: date.
        """
    A = string
    try:
        from dateutil.parser import parse
        return parse(A).date()
    except ImportError:
        return A


@classmethod
def from_json(cls, environment, json_body) ->'Organization':
    """
        Creates an Organization object from a JSON payload, for example when retrieving many orgs or organization searches
        :param environment: Datacenter
        :param json_body: JSON Payload
        :return: Organization
        :rtype: Organization
        """
    created_org = cls(environment)
    created_org.environment = environment
    created_org._get_details(json_body=json_body)
    return created_org


def p_start(p):
    """start : top_statement_list"""
    p[0] = p[1]


def psi_Mg_Na_HCO3_HMW84(T, P):
    """c-c'-a: magnesium sodium bicarbonate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def input_float(prompt=''):
    """Ask for a human float input.

    Args:
        prompt (string): Text to prompt as input.
    """
    while True:
        try:
            float_input = float(input(prompt))
        except ValueError:
            print('Please enter a float.\n')
            continue
        else:
            break
    return float_input


def pop_projection():
    """Remove the last projection matrix from the stack.

    """
    pass


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


def getSpan(array):
    """Return the span of `array`

    span(array) = max array(s) - min array(s)

    """
    return array.max() - array.min()


def is_connected(fd):
    """Checks the given file descriptor.

    :param int fd: File descriptor

    :rtype: bool
    """
    return False


def ipynb_vega_init():
    """Initialize the IPython notebook display elements

    This function borrows heavily from the excellent vincent package:
    http://github.com/wrobstory/vincent
    """
    try:
        from IPython.core.display import display, HTML
    except ImportError:
        print('IPython Notebook could not be loaded.')
    require_js = """
    if (window['d3'] === undefined) {{
        require.config({{ paths: {{d3: "http://d3js.org/d3.v3.min"}} }});
        require(["d3"], function(d3) {{
          window.d3 = d3;
          {0}
        }});
    }};
    if (window['topojson'] === undefined) {{
        require.config(
            {{ paths: {{topojson: "http://d3js.org/topojson.v1.min"}} }}
            );
        require(["topojson"], function(topojson) {{
          window.topojson = topojson;
        }});
    }};
    """
    d3_geo_projection_js_url = 'http://d3js.org/d3.geo.projection.v0.min.js'
    d3_layout_cloud_js_url = (
        'http://wrobstory.github.io/d3-cloud/d3.layout.cloud.js')
    topojson_js_url = 'http://d3js.org/topojson.v1.min.js'
    vega_js_url = 'http://trifacta.github.com/vega/vega.js'
    dep_libs = (
        """$.getScript("%s", function() {
        $.getScript("%s", function() {
            $.getScript("%s", function() {
                $.getScript("%s", function() {
                        $([IPython.events]).trigger("vega_loaded.vincent");
                })
            })
        })
    });"""
         % (d3_geo_projection_js_url, d3_layout_cloud_js_url,
        topojson_js_url, vega_js_url))
    load_js = require_js.format(dep_libs)
    html = '<script>' + load_js + '</script>'
    display(HTML(html))


def is_empty(string):
    """
    Is the string empty.

    :param string: The string to be tested.

    :Example:

    >>> from pygtftk.utils import is_empty
    >>> assert is_empty("")

    """
    return not string.strip()


def fil_clean_branch(branchs):
    """Remove * from current branch"""
    for branch in branchs:
        if '*' in branch:
            yield str(branch.split('* ')[1])
        else:
            yield branch


def heatmap(column_rel, **kwargs):
    """Plot a heatmap of data, probably from a column association call.

    This may be useful for other data frames, but most of the time you will
    want to call this like `edpanalyst.heatmap(popmod.mutual_information())`.
    """
    try:
        import seaborn as sns
    except ImportError:
        raise RuntimeError(
            'edpanalyst.heatmap requires that the "seaborn" python package be installed.'
            )
    plot_df = column_rel.fillna(0).reset_index()
    hmap = sns.clustermap(plot_df, linewidths=0.2, pivot_kws={'index': 'X',
        'columns': 'Y', 'values': 'I'}, **kwargs)
    for l in hmap.ax_heatmap.get_yticklabels():
        l.set_rotation('horizontal')
    return hmap


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

        :param SsoRemoveLoginUrlType val:
        :rtype: EventType
        """
    return cls('sso_remove_login_url', val)


@classmethod
def set_ssm_client(cls, client):
    """Override the default boto3 SSM client with your own."""
    required_methods = 'get_parameters', 'get_parameters_by_path'
    for method in required_methods:
        if not hasattr(client, method):
            raise TypeError('client must have a %s method' % method)
    cls._ssm_client = client


def get_current_version(config):
    """Return the current version of the config.

    :return: current config version or 0 if not defined
    """
    return config.get('CONFIG_VERSION', {}).get('CURRENT', 0)


def VoltageControlledVoltageSource(G):
    """VoltageControlledVoltageSource
    Voltage controlled voltage source
    @param G float or complex voltage gain
    @return list of list s-parameter matrix of a voltage controlled voltage source
    @remark
    The four port voltage controlled voltage source has
    the voltage sense element sensing the voltage difference between the plus terminal
    at port 1 and the minus terminal at port 2.

    The voltage generated by the amplifier has its positive terminal
    at port 4 and its negative terminal at port 3.

    """
    return [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [G, -G, 0.0, 1.0],
        [-G, G, 1.0, 0.0]]


def keyingset_button_add(all: bool=True):
    """Add current UI-active property to current keying set

    :param all: All, Add all elements of the array to a Keying Set
    :type all: bool
    """
    pass


def hide(unselected: bool=False):
    """Hide selected particles

    :param unselected: Unselected, Hide unselected rather than selected
    :type unselected: bool
    """
    pass


def normalize_column(df, column_name, new_column_name=None):
    """
    Normalize the given column in the given DatFrame linearly between 0 and 1.
    If no new_column_name is given the original data will be replaced.

    :param df: a pandas data frame that contains at least the given column_name
    :param column_name: a string that specifies the column name that should be normalized
    :param new_column_name: a string that specifies the column name of the normalized values
    :return: pandas DataFrame
    """
    if new_column_name is None:
        new_column_name = column_name
    column_min = df[column_name].min()
    column_max = df[column_name].max()
    df.loc[:, (new_column_name)] = (df[column_name] - column_min) / (column_max
         - column_min)
    return df


def group_add():
    """Add an object to a new group

    """
    pass


def no_os_popen(logical_line):
    """Disallow 'os.popen('

    Deprecated library function os.popen() Replace it using subprocess
    https://bugs.launchpad.net/tempest/+bug/1529836

    M329
    """
    if 'os.popen(' in logical_line:
        yield 0, 'M329 Deprecated library function os.popen(). Replace it using subprocess module. '


def getMember(unique_name):
    """Returns a IMember of the given name in the dimension."""


def pytest_configure_node(node):
    """ configure node information before it gets instantiated. """


def calculate(tmax_c, tmin_c, on_error=float('nan'), **kwargs):
    """Calculate the growing degree-days.

    The growing degree-days are calculated using the maximum and
    minimum daily air temperatures in degrees Celsius.  See:
    https://en.wikipedia.org/wiki/Growing_degree-day

    Parameters
    ----------
    tmax_c : float
        The maximum daily air temperature in degrees C.
    tmin_c : float
        The minimum daily air temperature in degrees C.
    on_error : optional, float('nan')
        The return value when an error occcurs during calculation.  May
        be any type, but preferably a float.
    tbase : optional, 10.0
        The base temperature, in degrees C.
    tmaxcutoff : optional, 999.0
        Sets the maximum value for the 'tmax_c' parameter.
    tmincutoff : optional, -999.0
        Sets the minimum value for the 'tmin_c" parameter.

    Returns
    -------
    float
        The growing degree-days calculated using Celsius values.  To
        convert, multiple the return value by (9.0 / 5.0).

    """
    tbase = kwargs.get('tbase', 10.0)
    tmaxcutoff = kwargs.get('tmaxcutoff', 999.0)
    tmincutoff = kwargs.get('tmincutoff', -999.0)
    try:
        _tmax = float(tmax_c)
        _tmin = float(tmin_c)
        _tbase = float(tbase)
        _tmaxcutoff = float(tmaxcutoff)
        _tmincutoff = float(tmincutoff)
        if _tmax > _tmaxcutoff:
            _tmax = _tmaxcutoff
        if _tmin < _tmincutoff:
            _tmin = _tmincutoff
        gdd = (_tmax + _tmin) / 2.0 - _tbase
        if gdd < 0.0:
            gdd = 0.0
    except:
        gdd = on_error
    return gdd


def p_node_test_3(p):
    """NodeTest : node_type LPAREN literal RPAREN"""
    if p[1] != 'processing-instruction':
        raise SyntaxError
    p[0] = 'processing-instruction', p[3]


def fly():
    """Interactively fly around the scene

    """
    pass


def main():
    """health check for Monasca-persister"""
    return 0


def avg_rating():
    """ return avg of rating """


def dic2hyperheader(dic):
    """
    Convert a Python dictionary into a hypercomplex block header list.

    Does not repack status from bit flags.
    """
    head = [0] * 9
    head[0] = dic['s_spare1']
    head[1] = dic['status']
    head[2] = dic['s_spare2']
    head[3] = dic['s_spare3']
    head[4] = dic['l_spare1']
    head[5] = dic['lpval1']
    head[6] = dic['rpval1']
    head[7] = dic['f_spare1']
    head[8] = dic['f_spare2']
    return head


def convert_by_vocab(vocab, items):
    """Converts a sequence of [tokens|ids] using the vocab."""
    output = []
    for item in items:
        output.append(vocab[item])
    return output


@classmethod
def facing_environment(cls, audio=True, **kwargs):
    """Convenience method to get the camera facing the environment (often the back)

        Parameters
        ----------
        audio: bool
            Capture audio or not
        kwargs:
            Extra keyword arguments passed to the `CameraStream`
        """
    return cls._facing(facing_mode='environment', audio=audio, **kwargs)


@staticmethod
def _sanitize_config(custom_config):
    """Checks whether ``custom_config`` is sane and returns a sanitized dict <str -> (str|object)>

    It checks if keys are all strings and sanitizes values of a given dictionary as follows:

    - If string, number or boolean is given as a value, it is converted to string.
      For string and number (int, float), it is converted to string by a built-in ``str()`` method.
      For a boolean value, ``True`` is converted to "true" instead of "True", and ``False`` is
      converted to "false" instead of "False", in order to keep the consistency with
      Java configuration.

    - If neither of the above is given as a value, it is inserted into the sanitized dict as it is.
      These values will need to be serialized before adding to a protobuf message.
    """
    if not isinstance(custom_config, dict):
        raise TypeError(
            'Component-specific configuration must be given as a dict type, given: %s'
             % str(type(custom_config)))
    sanitized = {}
    for key, value in custom_config.iteritems():
        if not isinstance(key, str):
            raise TypeError(
                'Key for component-specific configuration must be string, given: %s:%s'
                 % (str(type(key)), str(key)))
        if isinstance(value, bool):
            sanitized[key] = 'true' if value else 'false'
        elif isinstance(value, (str, int, float)):
            sanitized[key] = str(value)
        else:
            sanitized[key] = value
    return sanitized


def extract_activation(layer):
    """
    Extract activation from layer definition object

    Parameters
    ----------
    layer : Layer object
       Activation layer

    Returns
    -------
    string
        String value with Keras activation function

    """
    config = layer.get_config()
    return config['activation']


def init_tensorrt_params(sym, arg_params, aux_params):
    """
    Set weights in attributes of TensorRT nodes
    :param sym: Symbol, the symbol graph should contains some TensorRT nodes
    :param arg_params: arg_params
    :param aux_params: aux_params
    :return arg_params, aux_params: remaining params that are not in TensorRT nodes
    """
    arg_params = arg_params.copy()
    aux_params = aux_params.copy()
    for s in sym.get_internals():
        new_params_names = ''
        tensorrt_params = {}
        if 'subgraph_params_names' in s.list_attr():
            keys = s.list_attr()['subgraph_params_names'].split(';')
            for k in keys:
                if k in arg_params:
                    new_params_names += k + ';'
                    tensorrt_params['subgraph_param_' + k] = arg_params[k]
                    arg_params.pop(k)
                elif k in aux_params:
                    new_params_names += k + ';'
                    tensorrt_params['subgraph_param_' + k] = aux_params[k]
                    aux_params.pop(k)
            new_attrs = {}
            for k, v in tensorrt_params.items():
                new_attrs[k] = str(v.handle.value)
            if len(new_attrs) > 0:
                s._set_attr(**new_attrs)
                s._set_attr(subgraph_params_names=new_params_names[:-1])
    return arg_params, aux_params


def _bisearch(ucs, table, ubound):
    """
    Auxiliary function for binary search in interval table.

    :arg int ucs: Ordinal value of unicode character.
    :arg list table: List of starting and ending ranges of ordinal values,
        in form of ``[(start, end), ...]``.
    :rtype: int
    :returns: 1 if ordinal value ucs is found within lookup table, else 0.
    """
    lbound = 0
    if ucs < table[0][0] or ucs > table[ubound][1]:
        return 0
    while ubound >= lbound:
        mid = (lbound + ubound) // 2
        if ucs > table[mid][1]:
            lbound = mid + 1
        elif ucs < table[mid][0]:
            ubound = mid - 1
        else:
            return 1
    return 0


@classmethod
def spec(cls, *args, **kwargs):
    """This method exists only to give a more informative error message."""
    raise TypeError(
        'Specifications should either be bolts or spouts. Given: {!r}'.
        format(cls))


def keys():
    """ Return a list of keys from the dictionary """


def sibling(name):
    """
        A file path for the directory containing the file at this file path.

        @param name: the name of a sibling of this path. C{name} must be a
            direct sibling of this path and may not contain a path separator.

        @return: a sibling file path of this one.
        """


def setitem(L, idx, value):
    """setitem(x, idx, value) <==> x[idx] = value"""
    L[idx] = value


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


def is_uid_in_all_keys(uid, uids):
    """
    Check if uid is found in each of the uid lists for each SQL table
    :param uid: study instance uid
    :type uid: str
    :param uids: lists of study instance uids organized by SQL table
    :type uids: dict
    :return: True only if uid is found in each of the tables
    :rtype: bool
    """
    table_answer = {}
    for table in list(uids):
        table_answer[table] = False
    for table, value in uids.items():
        if uid in value:
            table_answer[table] = True
    final_answer = True
    for table, value in table_answer.items():
        if table not in 'unique':
            final_answer *= value
    return final_answer


@classmethod
def create(cls, filename, prefix='', suffix='\n'):
    """Create CommandLog from filename (overwrite/create)."""
    return cls(open(filename, 'wt'), prefix, suffix, own=True)


@classmethod
def supports_to_pcm(cls):
    """returns True if all necessary components are available
        to support the .to_pcm() method"""
    try:
        from audiotools.decoders import MP3Decoder
        return True
    except ImportError:
        return False


def collapse_hide_unused_toggle():
    """Toggle collapsed nodes and hide unused sockets

    """
    pass


@classmethod
def get_schema(cls):
    """Creates a table schema for incoming data from PlexxiCore.

        Returns a dictionary map of tablenames corresponding to column names
        for that table. Both tableNames and columnnames are strings.
        """
    d = {}
    d[cls.HOSTS] = 'uuid', 'name', 'mac_count', 'vmcount'
    d[cls.HOST_MACS] = 'Host_uuid', 'Mac_Address'
    d[cls.HOST_GUESTS] = 'Host_uuid', 'VM_uuid'
    d[cls.VMS] = 'uuid', 'name', 'host_uuid', 'ip', 'mac_count'
    d[cls.VM_MACS] = 'vmID', 'Mac_Address'
    d[cls.AFFINITIES] = 'uuid', 'name'
    d[cls.VSWITCHES] = 'uuid', 'host_count', 'vnic_count'
    d[cls.VSWITCHES_MACS] = 'vswitch_uuid', 'Mac_Address'
    d[cls.VSWITCHES_HOSTS] = 'vswitch_uuid', 'hostuuid'
    d[cls.PLEXXISWITCHES] = 'uuid', 'ip', 'status'
    d[cls.PLEXXISWITCHES_MACS] = 'Switch_uuid', 'Mac_Address'
    d[cls.PORTS] = 'uuid', 'name'
    d[cls.NETWORKLINKS] = ('uuid', 'name', 'port_uuid', 'start_uuid',
        'start_name', 'stop_uuid', 'stop_name')
    return d


@classmethod
def _seconds_to_minutes(cls, val, **kwargs):
    """
        converts a number of seconds to minutes
        """
    zero_value = kwargs.get('zero_value', 0)
    if val is not None:
        if val == zero_value:
            return 0
        return val / 60
    else:
        return 'Not Defined'


def vect(v1, v2):
    """Yields the vector product of `v1` and `v2`."""
    x1, y1, z1 = v1
    x2, y2, z2 = v2
    result = y1 * z2 - z1 * y2, x2 * z1 - x1 * z2, x1 * y2 - y1 * x2
    return result


def create_data_dir_name(pkg_name):
    """Return name of pkg's data directory."""
    return pkg_name + '_data'


def build_ldap_uri(config, node=''):
    """ Building LDAP uris for dovecot conf """
    if node:
        node += '_'
    return '{}://{}:{}'.format('ldaps' if config['ldap_secured'] == 'ssl' else
        'ldap', config['ldap_{}server_address'.format(node)], config[
        'ldap_{}server_port'.format(node)])


def from_mat(mat, i, j):
    """
    Placeholder for when we can fix the indexing with numpy arrays.
    """
    return mat[i, j]


@staticmethod
def _remove_line_ending(line: bytes):
    """
        To not have to deal with line endings in the data we can use this to
        remove them.
        """
    if line.endswith(b'\r\n'):
        return line[:-2]
    else:
        return line


def downsample_actor(actor, fact=0.5):
    """
    Reduce resolution of actor

    :param actor:
    :param fact:  (Default value = 0.5)

    """
    actor.decimate(fraction=fact)


def mask_value(vector, val):
    """
    Build a boolean mask around a certain value in the vector.

    Args:
        vector: 1-d ndarray of values
        val: values to mask on

    Returns:
        1-d boolean ndarray
    """
    return vector == val


def flatten_rsig(rsig):
    """
    Rsig -> byte array
    :param rsig:
    :return:
    """
    res = b''
    for i in range(len(rsig.asig.s0)):
        res += bytes(rsig.asig.s0[i])
    for i in range(len(rsig.asig.s1)):
        res += bytes(rsig.asig.s1[i])
    res += bytes(rsig.asig.ee)
    for i in range(len(rsig.Ci)):
        res += bytes(rsig.Ci[i])
    return res


@classmethod
def _convert_to_color(cls, color_spec):
    """
        Convert ``color_spec`` to an openpyxl v2 Color object
        Parameters
        ----------
        color_spec : str, dict
            A 32-bit ARGB hex string, or a dict with zero or more of the
            following keys.
                'rgb'
                'indexed'
                'auto'
                'theme'
                'tint'
                'index'
                'type'
        Returns
        -------
        color : openpyxl.styles.Color
        """
    from openpyxl.styles import Color
    if isinstance(color_spec, str):
        return Color(color_spec)
    else:
        return Color(**color_spec)


def get_sanitised_params(q, l):
    """Remove spaces from params and make lowercase."""
    query = q.lower().replace(' ', '_').replace('-', '_')
    loc = l.lower().replace(' ', '_').replace('-', '_')
    return query, loc


def _ternary_search_float(f, left, right, tol):
    """Trinary search: minimize f(x) over [left, right], to within +/-tol in x.

    Works assuming f is quasiconvex.
    """
    while right - left > tol:
        left_third = (2 * left + right) / 3
        right_third = (left + 2 * right) / 3
        if f(left_third) < f(right_third):
            right = right_third
        else:
            left = left_third
    return (right + left) / 2


def keyphrase_span(keyphrase):
    """Receive keyphrase and return label"""
    _, (_, start_end), _ = keyphrase
    return start_end


def dissolve():
    """Dissolve selected bones from the armature

    """
    pass


def trimval(thelist):
    """ Takes in number list or float and removes leading zeros """
    if type(thelist) == list:
        temp = []
        for i in thelist:
            if type(i) == int:
                temp.append(i)
            else:
                temp.append(float('%.4f' % i))
        thelist = temp
        return thelist
    elif type(thelist) == float:
        return float('%.4f' % thelist)
    return thelist


def exclude_directories():
    """List directory name patterns to be excluded"""
    return ['.*', 'CVS', '_darcs', '__pycache__', '.project', '.classpath',
        'nbproject', '.ideabuild', 'dist', 'EGG-INFO', '*.egg-info']


def _to_bytes(n, length, endianess='big'):
    """Partial python2 compatibility with int.to_bytes

    https://stackoverflow.com/a/20793663

    Parameters
    ----------
    n : TODO
        TODO
    length : TODO
        TODO
    endianess : str, TODO
        TODO

    Returns
    -------
    TODO
        TODO

    """
    if not hasattr(n, 'to_bytes'):
        h = '{:x}'.format(n)
        s = ('0' * (len(h) % 2) + h).zfill(length * 2).decode('hex')
        return s if endianess == 'big' else s[::-1]
    return n.to_bytes(length, endianess)


def word_map(hub, word, words, r_words):
    """
    Take a word and build it into the dict map. Modify the words dicts in place and then
    return the int that represents the given word
    """
    if word in words:
        return words[word]
    num = len(words) + 1
    words[word] = num
    r_words[num] = word
    return num


def _copy(data=None, out=None, name=None, **kwargs):
    """Returns a copy of the input.

    From:src/operator/tensor/elemwise_unary_op_basic.cc:246

    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 extract_params(loc):
    """ Extract parameters from locals """
    loc = loc.copy()
    loc.pop('self')
    return loc


def decode_utf16le(s):
    """
    decode_utf16le attempts to decode a bytestring as UTF-16LE.
      If the string has an odd length, or some unexpected feature,
      this function does its best to handle the data. It does not
      catch any Unicode-related exceptions, such as UnicodeDecodeError,
      so these should be handled by the caller.

    @type s: bytes
    @param s: a bytestring to pase
    @rtype: unicode
    @return: the unicode string decoded from `s`
    @raises: this function does not attempt to catch any Unicode-related exception, so the caller should handle these.
    """
    if b'\x00\x00' in s:
        index = s.index(b'\x00\x00')
        if index > 2:
            if s[index - 2] != b'\x00'[0]:
                s = s[:index + 2]
            else:
                s = s[:index + 3]
    if len(s) % 2 != 0:
        s = s + b'\x00'
    s = s.decode('utf16')
    s = s.partition('\x00')[0]
    return s