def extract_lzh(archive, compression, cmd, verbosity, interactive, outdir):
    """Extract a LZH archive."""
    opts = 'x'
    if verbosity > 1:
        opts += 'v'
    opts += 'w=%s' % outdir
    return [cmd, opts, archive]


def snap_selected_to_cursor(use_offset: bool=True):
    """Snap selected item(s) to cursor

    :param use_offset: Offset
    :type use_offset: bool
    """
    pass


def indexes(dic, keys=None):
    """ index dictionary by multiple keys

    Parameters
    ----------
    dic : dict
    keys : list

    Examples
    --------

    >>> d = {1:{"a":"A"},2:{"b":"B"}}
    >>> indexes(d,[1,'a'])
    'A'

    """
    keys = [] if keys is None else keys
    assert hasattr(dic, 'keys')
    new = dic.copy()
    old_key = None
    for key in keys:
        if not hasattr(new, 'keys'):
            raise KeyError('No indexes after: {}'.format(old_key))
        old_key = key
        new = new[key]
    return new


@staticmethod
def _format_measure(measure):
    """Format measure to correct type."""
    try:
        measure = int(measure)
    except ValueError:
        try:
            if float(measure) < 10:
                measure = float('{:.2f}'.format(round(float(measure), 2)))
            else:
                measure = float('{:.1f}'.format(round(float(measure), 1)))
        except ValueError:
            if measure == 'on':
                measure = True
            elif measure == 'off':
                measure = False
    return measure


def delete_repository(repositoryName=None):
    """
    Deletes a repository. If a specified repository was already deleted, a null repository ID will be returned.
    See also: AWS API Documentation

    :example: response = client.delete_repository(
        repositoryName='string'
    )

    :type repositoryName: string
    :param repositoryName: [REQUIRED]
            The name of the repository to delete.

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

    """
    pass


def getQueriables():
    """Return an iterable of objects that can be queried

        The returned obects should be two-tuples with:

        - A unicode id

          The id must uniquely identify the queriable object within
          the set of queriable objects. Furthermore, in subsequent
          calls, the same id should be used for a given queriable
          object.

        - A queriable object

          This is an object for which there is a view provided for
          searching for items.

        """


def get_instance_snapshot(instanceSnapshotName=None):
    """
    Returns information about a specific instance snapshot.
    See also: AWS API Documentation

    :example: response = client.get_instance_snapshot(
        instanceSnapshotName='string'
    )

    :type instanceSnapshotName: string
    :param instanceSnapshotName: [REQUIRED]
            The name of the snapshot for which you are requesting information.

    :rtype: dict
    :return: {
        'instanceSnapshot': {
            'name': 'string',
            'arn': 'string',
            'supportCode': 'string',
            'createdAt': datetime(2015, 1, 1),
            'location': {
                'availabilityZone': 'string',
                'regionName': 'us-east-1'|'us-west-1'|'us-west-2'|'eu-west-1'|'eu-central-1'|'ap-south-1'|'ap-southeast-1'|'ap-southeast-2'|'ap-northeast-1'|'ap-northeast-2'
            },
            'resourceType': 'Instance'|'StaticIp'|'KeyPair'|'InstanceSnapshot'|'Domain'|'PeeredVpc',
            'state': 'pending'|'error'|'available',
            'progress': 'string',
            'fromInstanceName': 'string',
            'fromInstanceArn': 'string',
            'fromBlueprintId': 'string',
            'fromBundleId': 'string',
            'sizeInGb': 123
        }
    }

    """
    pass


@classmethod
def remove_organization(cls, options=None):
    """Disassociate an organization"""
    cls.command_sub = 'remove-organization'
    return cls.execute(cls._construct_command(options))


@staticmethod
def iter_properties(sheet):
    """ Iterate on properties in css. """
    for rule in sheet:
        if rule.type == rule.STYLE_RULE:
            for prop in rule.style:
                yield prop


def unindent():
    """Delete 4 spaces from line beginning

    """
    pass


def _get_normalized_vm_statuses(vm_iv):
    """Iterate over a list of virtual machine statuses and normalize them.

    Arguments:
        vm_iv (VirtualMachineInstanceView): Virtual Machine Instance View

    Returns:
        dict: Normalized virtual machine statuses

    """
    normalized_statuses = {}
    for s in vm_iv.statuses:
        if s.code.startswith('PowerState/'):
            code_elements = s.code.split('/', 1)
            normalized_statuses['power_state'] = code_elements[1].lower()
    return normalized_statuses


@staticmethod
def writeChar(value):
    """ Write a single-character string as a one-byte (u8) number. """
    return 0 if value is None else ord(value[0])


def get_dates(df, date_column):
    """Converts a given date to various formats and returns an updated dataframe.

    Args:
        df: Pandas dataframe.
        columns: List of columns to transform.

    Returns:
        Original dataframe with additional date columns.
    """
    df['day'] = df[date_column].dt.strftime('%d')
    df['month'] = df[date_column].dt.strftime('%m')
    df['year'] = df[date_column].dt.strftime('%Y')
    df['year_month'] = df[date_column].dt.strftime('%Y%m')
    df['week_number'] = df[date_column].dt.strftime('%U')
    df['day_number'] = df[date_column].dt.strftime('%j')
    df['day_name'] = df[date_column].dt.strftime('%A')
    df['month_name'] = df[date_column].dt.strftime('%B')
    df['mysql_date'] = df[date_column].dt.strftime('%Y-%d-%m')
    return df


def clean_path(path):
    """
        Strip a path of its last '/' if there is one
    """
    if path[-1] == '/':
        return path[:-1]
    return path


def startswith_whitespace(text):
    """ Check if text starts with a whitespace

    If text is not a string return False
    """
    if not isinstance(text, str):
        return False
    return text[:1].isspace()


def is_pc(note):
    """check if note has the same format as pc, return boolean"""
    return note in range(12)


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 create_cone(bm: 'bmesh.types.BMesh', cap_ends: bool, cap_tris: bool,
    segments: int, diameter1: float, diameter2: float, depth: float, matrix:
    'mathutils.Matrix', calc_uvs: bool) ->dict:
    """Creates a cone with variable depth at both ends

    :param bm: The bmesh to operate on.
    :type bm: 'bmesh.types.BMesh'
    :param cap_ends: whether or not to fill in the ends with faces
    :type cap_ends: bool
    :param cap_tris: fill ends with triangles instead of ngons
    :type cap_tris: bool
    :param segments: Undocumented.
    :type segments: int
    :param diameter1: diameter of one end
    :type diameter1: float
    :param diameter2: diameter of the opposite
    :type diameter2: float
    :param depth: distance between ends
    :type depth: float
    :param matrix: matrix to multiply the new geometry with
    :type matrix: 'mathutils.Matrix'
    :param calc_uvs: calculate default UVs
    :type calc_uvs: bool
    :return:  verts: output vertstype list of (bmesh.types.BMVert)
    """
    pass


@staticmethod
def out_back(progress):
    """.. image:: images/anim_out_back.png
        """
    p = progress - 1.0
    return p * p * ((1.70158 + 1) * p + 1.70158) + 1.0


def set_(data_type):
    """ Create an alias for a SetType that contains this data type """
    return frozenset([data_type])


@classmethod
def inc_key(cls):
    """ Get the key used to define a data_type include.

        Override this method to use a different keyword for 'data_type_inc'
        """
    return cls.__inc_key


def bipartition_of_one(seq):
    """Generate bipartitions where one part is of length 1."""
    seq = list(seq)
    for i, elt in enumerate(seq):
        yield (elt,), tuple(seq[:i] + seq[i + 1:])


def get_object_name(stroke):
    """Returns the name of the object that this stroke is drawn on."""
    fedge = stroke[0].fedge
    if fedge is None:
        return None
    return fedge.viewedge.viewshape.name


@classmethod
def promote_from_model(cls, _):
    """
        Creates an object of this type from the model primitive defining it.
        :param flytekit.models.literals.Literal _:
        :rtype: Void
        """
    return cls()


def list_data():
    """
    Lists the datasets which are available, and where they are located.
    """
    print('All datasets for the starlib package are in the ./data directory.')
    print('  ')
    print('Available datasets:')
    print('iris.csv')
    print('boston_house_prices.csv')
    print('weather.csv')
    print('  ')
    print('Each dataset has its own load utility.  For example, to load iris:')
    print('starlib.load_iris()')
    print('  ')
    print('Datasets are read using Pandas, i.e. pd.read_csv.')


def createMainWidget(argv):
    """
    Function to create the main widget.

    @param argv list of commandline parameters (list of strings)
    @return reference to the main widget (QWidget)
    """
    from UI.DiffDialog import DiffWindow
    return DiffWindow()


@staticmethod
def _check_prob_choice_mode_compat(probability_mode, choice_mode):
    """
        Check that the probability and choice modes are compatibly with
        each other. Currently 'single_chooser' must be paired with
        'aggregate' and 'full_product' must be paired with 'individual'.

        """
    if probability_mode == 'full_product' and choice_mode == 'aggregate':
        raise ValueError(
            "'full_product' probability mode is not compatible with 'aggregate' choice mode"
            )
    if probability_mode == 'single_chooser' and choice_mode == 'individual':
        raise ValueError(
            "'single_chooser' probability mode is not compatible with 'individual' choice mode"
            )


def gcd2(a, b):
    """Greatest common divisor using Euclid's algorithm."""
    while a:
        a, b = b % a, a
    return b


@classmethod
def find_one(cls, query=None, doc_id=None):
    """Return a single object matching the query"""
    if doc_id is not None:
        result = cls.find(query, doc_ids=[doc_id])
    else:
        result = cls.find(query)
    try:
        return next(iter(result))
    except StopIteration:
        return None


def expanded_toggle():
    """Expand/Collapse all items

    """
    pass


def isatty(fh):
    """Return true if the process has a controlling terminal."""
    try:
        return fh.isatty()
    except AttributeError:
        pass


@staticmethod
def _get_parent_dn(dn):
    """
        Gets the dn of the parent object
        Meant to be overridden by inheriting classes.
        Raises exception if not overridden.

        :returns: string containing dn
        """
    return dn.split('/dom-')[0]


@staticmethod
def p_measurement_optional_list_optional(p):
    """measurement_optional_list_optional : empty
                                              | measurement_optional_list"""
    p[0] = tuple() if p[1] is None else p[1]


@classmethod
def get_object(cls, api_token, domain_name, mocked):
    """
            Class method that will return a Domain object by ID.
        """
    domain = cls(token=api_token, name=domain_name, mocked=mocked)
    domain.mock_data = 'domains/single.json'
    domain.load()
    return domain


def col_defn(col_data, i):
    """
    returns individual column creation statement; excluding indexes and keys

    used with iterations, i = str(i) where i is index of current iterations
    """
    sql_stmt = ' {name_' + i + '} {type_' + i + '}'
    type_field = col_data['type_' + i]
    if type_field in ['bit', 'tinyint', 'smallint', 'mediumint', 'int',
        'integer', 'bigint', 'decimal', 'numeric', 'char', 'varchar',
        'binary', 'varbinary']:
        sql_stmt += '({length_' + i + '})' if col_data['length_' + i] else ''
    if type_field in ['tinyint', 'smallint', 'mediumint', 'int', 'integer',
        'bigint', 'real', 'double', 'float', 'decimal', 'numeric']:
        sql_stmt += ' UNSIGNED' if 'unsigned' in col_data['other_' + i] else ''
    if type_field in ['set', 'enum']:
        sql_stmt += ' {values_' + i + '}' if col_data['values_' + i] else ''
    if type_field in ['tinytext', 'text', 'mediumtext', 'longtext']:
        sql_stmt += ' BINARY' if 'binary' in col_data['other_' + i] else ''
    if type_field in ['char', 'varchar', 'tinytext', 'text', 'mediumtext',
        'longtext', 'enum', 'set']:
        sql_stmt += ' CHARACTER SET {charset_' + i + '}'
    sql_stmt += ' AUTO_INCREMENT' if 'auto increment' in col_data['other_' + i
        ] else ''
    sql_stmt += ' NOT NULL' if 'not null' in col_data['other_' + i
        ] else ' NULL'
    d = {'primary': 'PRIMARY KEY', 'unique': 'UNIQUE', 'index': 'INDEX'}
    key_field = col_data['key_' + i]
    if key_field:
        sql_stmt += ' ' + d[key_field]
    return sql_stmt


def Dataframe2GSLIB(data_file, df):
    """Convert pandas DataFrame to a GSLIB Geo-EAS file for use with GSLIB
    methods.

    :param data_file: file name
    :param df: dataframe
    :return: None
    """
    ncol = len(df.columns)
    nrow = len(df.index)
    with open(data_file, 'w') as f:
        f.write(data_file + '\n')
        f.write(str(ncol) + '\n')
        for icol in range(ncol):
            f.write(df.columns[icol] + '\n')
        for irow in range(nrow):
            for icol in range(ncol):
                f.write(str(df.iloc[irow, icol]) + ' ')
            f.write('\n')


def convert_to_list(item):
    """If item is not list class instance or None put inside a list.

    :param item: object to be checked and converted
    :return: original item if it is a list instance or list containing the item.
    """
    return item if item is None or isinstance(item, list) else [item]


def findTargets(source, maxDepth=1, filter=None):
    """Given a source, iterate over objects to which it points.

        maxDepth is the number of relationships through which the search
        should walk transitively.  It must be a positive integer.

        filter is an optional callable that takes a relationship and returns
        a boolean True value if it should be included, and a False if not.
        """


@classmethod
def nrows_from_dims(cls, oncv_dims):
    """Return the number of rows from a dictionary with the dimensions."""
    raise NotImplementedError('Subclasses should define nrows_from_dims')


def p_estatuto(p):
    """estatuto : asignacion
                | condicion
                | when
                | in ';'
                | out
                | ciclo_w
                | ciclo_f
                | llamada ';'
                | llamada_graph ';'
                | open ';'
    """


def sample_color(location: int=(0, 0), merged: bool=False, palette: bool=False
    ):
    """Use the mouse to sample a color in the image

    :param location: Location
    :type location: int
    :param merged: Sample Merged, Sample the output display color
    :type merged: bool
    :param palette: Add to Palette
    :type palette: bool
    """
    pass


def safe_no_dnn_workmem_bwd(workmem):
    """
    Make sure the user is not attempting to use dnn.conv.workmem_bwd`.
    """
    if workmem:
        raise RuntimeError(
            'The option `dnn.conv.workmem_bwd` has been removed and should not be used anymore. Please use the options `dnn.conv.algo_bwd_filter` and `dnn.conv.algo_bwd_data` instead.'
            )
    return True


def replace_missing_ambiguous(seq, missing_ambiguous_list):
    """Given sequence and list of missing or ambiguous characters,
    replace them in sequence with '-'.
    """
    for char in missing_ambiguous_list:
        seq = seq.replace(char, '-')
    return seq


def _detect_future_imports(session):
    """
    Detect all __future__ imports. Since these imports must come first in
    the source code, these are attempt to be detected outside of other
    spidering.

    Parameters
    ----------
    session: dictionary
        globals() from the user's environment
    """
    imports = []
    for k in list(session.keys()):
        v = session[k]
        if hasattr(v, '__module__'):
            if v.__module__ == '__future__':
                if k is 'print_function':
                    continue
                if not k.startswith('_'):
                    imports.append('from __future__ import %s' % k)
    return imports


@staticmethod
def _symbol(rvs, crvs):
    """
        Returns H for a conditional entropy, and I for all other atoms.
        """
    return 'H' if len(rvs) == 1 else 'I'


def int32(value):
    """Validate a 'int32' method parameter type"""
    value = int(value)
    if value > 2147483647:
        raise ValueError('{} exceeds upper bound for int32'.format(value))
    if value < -2147483648:
        raise ValueError('{} below lower bound for int32'.format(value))


def delete_config_rule(ConfigRuleName=None):
    """
    Deletes the specified AWS Config rule and all of its evaluation results.
    AWS Config sets the state of a rule to DELETING until the deletion is complete. You cannot update a rule while it is in this state. If you make a PutConfigRule or DeleteConfigRule request for the rule, you will receive a ResourceInUseException .
    You can check the state of a rule by using the DescribeConfigRules request.
    See also: AWS API Documentation

    :example: response = client.delete_config_rule(
        ConfigRuleName='string'
    )

    :type ConfigRuleName: string
    :param ConfigRuleName: [REQUIRED]
            The name of the AWS Config rule that you want to delete.

    """
    pass


def list_ace(archive, compression, cmd, verbosity, interactive):
    """List an ACE archive."""
    cmdlist = [cmd]
    if verbosity > 1:
        cmdlist.append('v')
    else:
        cmdlist.append('l')
    cmdlist.append(archive)
    return cmdlist


def _update_removing(target, changes):
    """Like dict.update(), but remove keys where the value is None.
    """
    for k, v in changes.items():
        if v is None:
            target.pop(k, None)
        else:
            target[k] = v


def error_message(e, message=None, cause=None):
    """
    Formats exception message + cause
    :param e:
    :param message:
    :param cause:
    :return: formatted message, includes cause if any is set
    """
    if message is None and cause is None:
        return None
    elif message is None:
        return '%s, caused by %r' % (e.__class__, cause)
    elif cause is None:
        return message
    else:
        return '%s, caused by %r' % (message, cause)


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 clone(U):
    """
    Clones an ultrametric
    """
    import ophac.dtypes as dt
    U2 = dt.DistMatrix(U)
    U2._basePartition = U._basePartition
    return U2


def to_min(datetime):
    """
    Converts a datetime to an int representation in minutes. To do the reverse
    use: min_to_datetime.

    Parameters
    ----------
    datetime : datetime.datetime
        Represents a datetime in datetime"s format.

    Returns
    -------
    minutes : int
        Represents minutes from.

    Examples
    --------
    """
    minutes = int((datetime - datetime.utcfromtimestamp(0)).total_seconds() /
        60)
    return minutes


def no_cast(s):
    """Dummy function to cast a string to a string.

    Args:
        s (str): String to cast.

    Returns:
        str: Cast string.

    """
    return s


def separate_texts_by_languages(texts):
    """
    Takes a list of texts and returns a new dict of texts separated by language.

    :param texts:
    :return:
    """
    dict = {}
    for text in texts:
        lan = text.language
        if lan not in dict:
            dict[lan] = []
        dict[lan].append(text)
    return dict


def approximated_atmo_spectrum(energy):
    """Gives an approximated atmospheric neutrino spectrum.
    Can be used for comparing expected true energy distribution to recorded
    energy proxy distributions. It is normalised such that the weight for an
    energy of 1 is equal to 1. (It is agnostic to energy units)

    :param energy: True neutrino energy (in some consistent unit)
    :return: Spectrum weight for that energy
    """
    return energy ** -3.7


@classmethod
def get_polymorphic_types(cls):
    """
        Return the list of accepted types.
        """
    return cls._poly_type_serializer_map.keys()


def colgen(*lstcol, **kargs):
    """Returns a generator that mixes provided quantities forever
    trans: a function to convert the three arguments into a color. lambda x,y,z:(x,y,z) by default"""
    if len(lstcol) < 2:
        lstcol *= 2
    trans = kargs.get('trans', lambda x, y, z: (x, y, z))
    while True:
        for i in range(len(lstcol)):
            for j in range(len(lstcol)):
                for k in range(len(lstcol)):
                    if i != j or j != k or k != i:
                        yield trans(lstcol[(i + j) % len(lstcol)], lstcol[(
                            j + k) % len(lstcol)], lstcol[(k + i) % len(
                            lstcol)])


def remove_constant_features(sfm):
    """
    Remove features that are constant across all samples
    """
    x_not_equal_to_1st_row = sfm._x != sfm._x[0]
    non_const_f_bool_ind = x_not_equal_to_1st_row.sum(axis=0) >= 1
    return sfm.ind_x(selected_f_inds=non_const_f_bool_ind)


def showOperandLines(rh):
    """
    Produce help output related to operands.

    Input:
       Request Handle
    """
    if rh.function == 'HELP':
        rh.printLn('N', '  For the MakeVM function:')
    else:
        rh.printLn('N', 'Sub-Functions(s):')
    rh.printLn('N', '      directory     - ' +
        'Create a virtual machine in the z/VM user directory.')
    rh.printLn('N', '      help          - Displays this help information.')
    rh.printLn('N', '      version       - ' +
        'show the version of the makeVM function')
    if rh.subfunction != '':
        rh.printLn('N', 'Operand(s):')
        rh.printLn('N', '      --cpus <cpuCnt>       - ' +
            'Specifies the desired number of virtual CPUs the')
        rh.printLn('N', '                              ' + 'guest will have.')
        rh.printLn('N', '      --maxcpu <maxCpuCnt>  - ' +
            'Specifies the maximum number of virtual CPUs the')
        rh.printLn('N', '                              ' +
            'guest is allowed to define.')
        rh.printLn('N', '      --ipl <ipl>           - ' +
            'Specifies an IPL disk or NSS for the virtual')
        rh.printLn('N', '                              ' +
            "machine's directory entry.")
        rh.printLn('N', '      --logonby <byUsers>   - ' +
            'Specifies a list of up to 8 z/VM userids who can log')
        rh.printLn('N', '                              ' +
            'on to the virtual machine using their id and password.')
        rh.printLn('N', '      --maxMemSize <maxMem> - ' +
            'Specifies the maximum memory the virtual machine')
        rh.printLn('N', '                              ' +
            'is allowed to define.')
        rh.printLn('N', '      --setReservedMem      - ' +
            'Set the additional memory space (maxMemSize - priMemSize)')
        rh.printLn('N', '                              ' +
            'as reserved memory of the virtual machine.')
        rh.printLn('N', '      <password>            - ' +
            'Specifies the password for the new virtual')
        rh.printLn('N', '                              ' + 'machine.')
        rh.printLn('N', '      <priMemSize>          - ' +
            'Specifies the initial memory size for the new virtual')
        rh.printLn('N', '                              ' + 'machine.')
        rh.printLn('N', '      <privClasses>         - ' +
            'Specifies the privilege classes for the new virtual')
        rh.printLn('N', '                              ' + 'machine.')
        rh.printLn('N', '      --profile <profName>  - ' +
            'Specifies the z/VM PROFILE to include in the')
        rh.printLn('N', '                              ' +
            "virtual machine's directory entry.")
        rh.printLn('N', '      <userid>              - ' +
            'Userid of the virtual machine to create.')
    return


def fetchiter(cursor, arraysize=10000):
    """Generator for cursor results"""
    while True:
        rows = cursor.fetchmany(arraysize)
        print(rows)
        if rows == []:
            break
        for row in rows:
            yield row


def datatype_not_implemented(field, value):
    """A datatype was not yet implemented or decided upon."""
    pass


def clone(ctx, path_base, repo_url, dir_target):
    """Clones a remote repository.

    .. warning:: Make sure ~/.config is not created beforehand with sudo, otherwise you get:
        unable to access '/home/XXX/.config/git/attributes'

    """
    if 'github' in repo_url:
        ctx.run('ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts', warn
            =True)
        ctx.run('ssh -T git@github.com', warn=True)
    with ctx.cd(path_base):
        ctx.run('git clone -v %s %s' % (repo_url, dir_target))


@staticmethod
def page_fn_footer(canvas, doc):
    """ A footer with the print date on the left and the page numbers
        on the right.

        """
    canvas.saveState()
    canvas.setFont('Helvetica', 9)
    canvas.drawString(doc.leftMargin, doc.bottomMargin / 2,
        f'Druckdatum: {doc.created}')
    canvas.drawRightString(doc.pagesize[0] - doc.rightMargin, doc.
        bottomMargin / 2, f'{canvas._pageNumber}')
    canvas.restoreState()


def _strxfrm(s):
    """ strxfrm(string) -> string.
        Returns a string that behaves for cmp locale-aware.
    """
    return s


def pairwise(iterable):
    """s -> (s0,s1), (s2,s3), (s4, s5), ..."""
    a = iter(iterable)
    return zip(a, a)


@classmethod
def from_str(cls, s, rs=None):
    """Parses a variant object from a str of the form chrXX:YYYY_R/A.

        :param s: The string to parse the SNP from (Format: chrXX:YYY_R/A).
        :param rs: An optional parameter specifying the rs number.

        :returns: A list of SNP objects.

        If it is a multi-allelic loci, the list will contain one SNP per
        alternative allele.

        If it is not, this will be a list of length 1...

        """
    s = s.lstrip('chr')
    chrom, s = s.split(':')
    pos, s = s.split('_')
    alleles = s.split('/')
    ref = alleles[0]
    alts = list(alleles[1:])
    var_list = []
    for alt in alts:
        v = cls(chrom, pos, rs, ref, alt)
        var_list.append(v)
    return var_list


def _format_select(formatter, name):
    """Modify the query selector by applying any formatters to it.

    Parameters
    ----------
    formatter : str
       Hyphen-delimited formatter string where formatters are
       applied inside-out, e.g. the formatter string
       SEC_TO_MICRO-INTEGER-FORMAT_UTC_USEC applied to the selector
       foo would result in FORMAT_UTC_USEC(INTEGER(foo*1000000)).
    name: str
        The name of the selector to apply formatters to.

    Returns
    -------
    str
        The formatted selector
    """
    for caster in formatter.split('-'):
        if caster == 'SEC_TO_MICRO':
            name = '%s*1000000' % name
        elif ':' in caster:
            caster, args = caster.split(':')
            name = '%s(%s,%s)' % (caster, name, args)
        else:
            name = '%s(%s)' % (caster, name)
    return name


@staticmethod
def _dimensions_to_values(dimensions):
    """
        Replace dimensions specs with their `dimension`
        values, and ignore those without
        """
    values = []
    for dimension in dimensions:
        if isinstance(dimension, dict):
            if 'extractionFn' in dimension:
                values.append(dimension)
            elif 'dimension' in dimension:
                values.append(dimension['dimension'])
        else:
            values.append(dimension)
    return values


def load(path, binary=False):
    """Return the content of the file"""
    if binary:
        mode = 'rb'
    else:
        mode = 'r'
    fd = open(path, mode)
    content = fd.read()
    fd.close()
    return content


def pytest_assume_fail(lineno, entry):
    """
    Hook to manipulate user-defined data in-case of assumption failure.
    lineno: Line in the code from where asumption failed.
    entry: The assumption failure message generated from assume() call
    """
    pass


def get_first_element(xml, name):
    """Return the first found element
        """


def delete(record_id, table):
    """Delete the record and data of a member in a specific table."""
    return


@classmethod
def build_url(cls, config, namespace, name):
    """ Build a url for a repository """
    return config['host'] + '/' + namespace + '/' + name + '.git'


def simple_merge_handler(previous_props, next_props):
    """Merge properties if the keys on old and new are disjoint.

    Return a mapping containing the values from both old and new properties,
    but only if there is no key that exists in both.
    """
    for name, value in previous_props.items():
        if name in next_props and value != next_props[name]:
            raise ValueError(
                'Cannot merge - {0} changed (old value: {1},  new value: {2})'
                .format(name, value, next_props[name]))
        if name not in next_props:
            next_props[name] = value
    return next_props


def interpret_options_from_string(st):
    """
    Converts a string into a dictionary.

    @param      st      string
    @return             evaluated object
    """
    if isinstance(st, dict):
        return st
    value = eval(st)
    return value


def isolated_connection():
    """
        Context manager that opens a new, distinct connection and
        returns its cursor.

        No matter what happens in the ``with`` block, the connection will be
        dropped afterwards.
        """


def parseSyslog(msg):
    """Parses Syslog messages (RFC 5424)

    The `Syslog Message Format (RFC 5424)
    <https://tools.ietf.org/html/rfc5424#section-6>`_ can be parsed with
    simple whitespace tokenization::

        SYSLOG-MSG = HEADER SP STRUCTURED-DATA [SP MSG]
        HEADER     = PRI VERSION SP TIMESTAMP SP HOSTNAME
                     SP APP-NAME SP PROCID SP MSGID
        ...
        NILVALUE   = "-"

    This method does not return STRUCTURED-DATA.  It parses NILVALUE
    ("-") STRUCTURED-DATA or simple STRUCTURED-DATA which does not
    contain (escaped) ']'.

    :returns: A dictionary keyed by the constituent parts of the
    Syslog message.
    """
    tokens = msg.split(' ', 6)
    result = {}
    if len(tokens) > 0:
        pri = tokens[0]
        start = pri.find('<')
        stop = pri.find('>')
        if start != -1 and stop != -1:
            result['pri'] = pri[start + 1:stop]
        else:
            result['pri'] = ''
        if stop != -1 and len(pri) > stop:
            result['version'] = pri[stop + 1:]
        else:
            result['version'] = ''
    result['timestamp'] = tokens[1] if len(tokens) > 1 else ''
    result['hostname'] = tokens[2] if len(tokens) > 2 else ''
    result['appname'] = tokens[3] if len(tokens) > 3 else ''
    result['procid'] = tokens[4] if len(tokens) > 4 else ''
    result['msgid'] = tokens[5] if len(tokens) > 5 else ''
    result['msg'] = ''
    if len(tokens) > 6:
        rest = tokens[6]
        start = rest.find('-')
        if start == -1:
            start = rest.find(']')
        if len(rest) > start:
            result['msg'] = rest[start + 1:].strip()
    return result


def create_task(conn, task):
    """
    Create a new task
    :param conn:
    :param task:
    :return:
    """
    sql = """ INSERT INTO vencodes(name,priority,status_id,project_id,begin_date,end_date)
              VALUES(?,?,?,?,?,?) """
    cur = conn.cursor()
    cur.execute(sql, task)
    return cur.lastrowid


@classmethod
def from_json(cls, json: dict):
    """load the Deck object from json"""
    try:
        del json['p2th_wif']
    except KeyError:
        pass
    return cls(**json)


def provider_parser(subparser):
    """Generate a provider parser for Sakura Cloud"""
    subparser.add_argument('--auth-token', help=
        'specify access token for authentication')
    subparser.add_argument('--auth-secret', help=
        'specify access secret for authentication')


def import_messages(file):
    """ Import messages into mailing list archive """


def log10(data=None, out=None, name=None, **kwargs):
    """Returns element-wise Base-10 logarithmic value of the input.

    ``10**log10(x) = x``

    The storage type of ``log10`` output is always dense

    Defined in src/operator/tensor/elemwise_unary_op_logexp.cc:L93

    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 remove_agent_url(node):
    """Helper to remove the agent_url record."""
    info = node.driver_internal_info
    info.pop('agent_url', None)
    node.driver_internal_info = info


def __len__():
    """Return the number of entries in the manifest."""


def properties():
    """Toggle the properties region visibility

    """
    pass


def _centroid(vertices):
    """Find the centroid of a polygon."""
    assert vertices[0] == vertices[-1]
    thesum = 0
    vsum = 0, 0
    for i in range(len(vertices) - 1):
        v1 = vertices[i]
        v2 = vertices[i + 1]
        cross = v1[0] * v2[1] - v1[1] * v2[0]
        thesum += cross
        vsum = (v1[0] + v2[0]) * cross + vsum[0], (v1[1] + v2[1]
            ) * cross + vsum[1]
        z = 1.0 / (3.0 * thesum)
    return vsum[0] * z, vsum[1] * z


def send_arduino_simple(msg, serial_connection):
    """
    Send the *msg* over the *serial_connection*

    Same as :code:`send_arduino`, but doesn't add anything to the message
    before sending it.

    Parameters
    ----------
    msg : str or bytes
        the message you want to send
    serial_connection : object
        the :code:`serial.Serial` object you want to use for sending
    """
    if not isinstance(msg, bytes):
        msg = str(msg).encode()
    serial_connection.write(msg)


def shutdown():
    """
    This clear the current map from memory.
    """
    global CurrentMap
    del CurrentMap
    CurrentMap = None


def copyFieldIfExists(fromDic, toDic, keys):
    """
    Copy the field at name from fromDic to toDic only if it exists
    @param fromDic: Origin Dictionary
    @param toDic: Destination Dictionary
    @param keys: Array of keys of the elements to copy
    """
    for key in keys:
        if key in fromDic:
            toDic[key] = fromDic[key]


def message_from_str(src):
    """MessageString is a simple length restricted string:

    <xs:simpleType name="MessageString">
            <xs:restriction base="xs:string">
                    <xs:maxLength value="1024"/>
            </xs:restriction>
    </xs:simpleType>"""
    if len(src) > 1024:
        raise ValueError('MessageString exceeds 1024 characters: %s' % src)
    return src


def isLogin(oldPayload):
    """ 验证是否已登录，登录则更新token
    --
        @return 错误返回 False
        @return 成功返回 True
    """
    if oldPayload == None:
        return False
    return True


def renderRow(item):
    """Render a row for the given item.

        Uses renderCells."""


def get_nodes_count(bpmn_graph, node_type=None):
    """
    Gets the count of nodes of the requested type.
    If no type is provided,
    the count of all nodes in BPMN diagram graph is returned.

    :bpmn_graph: an instance of BpmnDiagramGraph representing BPMN model.
    :param node_type: string with valid BPMN XML tag name
                      (e.g. 'task', 'sequenceFlow').
    """
    return len(bpmn_graph.get_nodes(node_type=node_type))


@staticmethod
def is_multizone_reader():
    """Can this reader read bundles which contain more zones?.

        This implementation returns always True.
        If a subclass supports just one zone in file (e.g. `read.Sentences`),
        this method should be overriden to return False, so `process_document`
        can take advatage of this knowledge and optimize the reading
        (no buffer needed even if `bundles_per_doc` specified).
        """
    return True


def _auto_add_extension(file_name, engine):
    """Make sure a file name has an extension that reflects its
    file type.
    """
    if '.h5' not in file_name and '.nc' not in file_name:
        extension = '.h5' if engine == 'h5netcdf' else '.nc'
        file_name += extension
    return file_name


def get_calculator_impstr(calculator_name):
    """
    Returns the import string for the calculator
    """
    if calculator_name.lower() == 'gpaw' or calculator_name is None:
        return 'from gpaw import GPAW as custom_calculator'
    elif calculator_name.lower() == 'espresso':
        return 'from espresso import espresso as custom_calculator'
    else:
        possibilities = {'abinit': 'abinit.Abinit', 'aims': 'aims.Aims',
            'ase_qmmm_manyqm': 'AseQmmmManyqm', 'castep': 'Castep',
            'dacapo': 'Dacapo', 'dftb': 'Dftb', 'eam': 'EAM', 'elk': 'ELK',
            'emt': 'EMT', 'exciting': 'Exciting', 'fleur': 'FLEUR',
            'gaussian': 'Gaussian', 'gromacs': 'Gromacs', 'mopac': 'Mopac',
            'morse': 'MorsePotential', 'nwchem': 'NWChem', 'siesta':
            'Siesta', 'tip3p': 'TIP3P', 'turbomole': 'Turbomole', 'vasp':
            'Vasp'}
        current_val = possibilities.get(calculator_name.lower())
        package, class_name = (calculator_name, current_val
            ) if current_val else calculator_name.rsplit('.', 1)
        return 'from ase.calculators.{} import {} as custom_calculator'.format(
            package, class_name)


def mute_string(text):
    """Replace contents with 'xxx' to prevent syntax matching.

    >>> mute_string('"abc"')
    '"xxx"'
    >>> mute_string("'''abc'''")
    "'''xxx'''"
    >>> mute_string("r'abc'")
    "r'xxx'"
    """
    start = text.index(text[-1]) + 1
    end = len(text) - 1
    if text[-3:] in ('"""', "'''"):
        start += 2
        end -= 2
    return text[:start] + 'x' * (end - start) + text[end:]


def _delete_duplicates(l, keep_last):
    """Delete duplicates from a sequence, keeping the first or last."""
    seen = set()
    result = []
    if keep_last:
        l.reverse()
    for i in l:
        try:
            if i not in seen:
                result.append(i)
                seen.add(i)
        except TypeError:
            result.append(i)
    if keep_last:
        result.reverse()
    return result


def print_line(line, env):
    """
    >>> from unidump.env import env
    >>> print_line([0, ['00A0', '00B0', '00C0'], 'ABC'], env(linelength=4))
          0    00A0 00B0 00C0         ABC

    >>> print_line([12, ['00A0', '1F678', '00C0'], 'A🙸C'],
    ...            env(linelength=4))
         12    00A0 1F678 00C0        A🙸C

    """
    env.output.write(env.lineformat.format(byte=line[0], repr=' '.join(line
        [1]).ljust(env.linelength * 5 - 1), data=line[2]))


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 _rle_decode(data):
    """
    Decodes run-length-encoded `data`.
    """
    if not data:
        return data
    new = b''
    last = b''
    for cur in data:
        if last == b'\x00':
            new += last * cur
            last = b''
        else:
            new += last
            last = bytes([cur])
    return new + last


def init_extern_user_native_field(apps, schema_editor):
    """
    初始化 extern_user 字段
    """
    subject = 'extern_user'
    NativeField = apps.get_model('oneid_meta', 'NativeField')
    for native_field in NativeField.objects.all():
        native_field.subject = 'user'
        native_field.save()
    NativeField.objects.create(subject=subject, name='手机号', key='mobile',
        is_visible_editable=False)
    NativeField.objects.create(subject=subject, name='邮箱', key='email',
        is_visible_editable=False)
    NativeField.objects.create(subject=subject, name='用户名', key='username',
        is_visible_editable=False)
    NativeField.objects.create(subject=subject, name='标签', key='nodes',
        schema={'type': 'array', 'items': {'type': 'object', 'properties':
        {'uid': {'type': 'string'}, 'name': {'type': 'string'}}}},
        is_visible_editable=False)
    NativeField.objects.create(subject=subject, name='姓名', key='name')
    NativeField.objects.create(subject=subject, name='备注', key='remark')


@staticmethod
def has_battery():
    """Return whether the device has a battery."""
    return False


def folder2ver(folder):
    """get the version number from the E+ install folder"""
    ver = folder.split('EnergyPlus')[-1]
    ver = ver[1:]
    splitapp = ver.split('-')
    ver = '.'.join(splitapp)
    return ver


def __correlate_fit_params(params, corr):
    """Apply correlation to the list of parameters with the covariance matrix"""
    for index1, param1 in enumerate(params):
        for index2, param2 in enumerate(params[index1 + 1:]):
            if param1.error == 0 or param2.error == 0:
                continue
            param1.set_covariance(param2, corr[index1][index2 + index1 + 1])


def flag(val):
    """Does the value look like an on/off flag?"""
    if val == 1:
        return True
    elif val == 0:
        return False
    val = str(val)
    if len(val) > 5:
        return False
    return val.upper() in ('1', '0', 'F', 'T', 'TRUE', 'FALSE', 'ON', 'OFF')


@classmethod
def String(cls, name, tokenized=False, omitNorms=True, indexOptions='DOCS',
    **settings):
    """Return Field with default settings for strings."""
    return cls(name, tokenized=tokenized, omitNorms=omitNorms, indexOptions
        =indexOptions, **settings)


def featurewise_norm(x, mean=None, std=None, epsilon=1e-07):
    """Normalize every pixels by the same given mean and std, which are usually
    compute from all examples.

    Parameters
    -----------
    x : numpy.array
        An image with dimension of [row, col, channel] (default).
    mean : float
        Value for subtraction.
    std : float
        Value for division.
    epsilon : float
        A small position value for dividing standard deviation.

    Returns
    -------
    numpy.array
        A processed image.

    """
    if mean:
        x = x - mean
    if std:
        x = x / (std + epsilon)
    return x


def standardize_sample_or_class_weights(x_weight, output_names, weight_type):
    """Maps `sample_weight` or `class_weight` to model outputs.

    # Arguments
        x_weight: User-provided `sample_weight` or `class_weight` argument.
        output_names: List of output names (strings) in the model.
        weight_type: A string used purely for exception printing.

    # Returns
        A list of `sample_weight` or `class_weight` where there are exactly
            one element per model output.

    # Raises
        ValueError: In case of invalid user-provided argument.
    """
    if x_weight is None or len(x_weight) == 0:
        return [None for _ in output_names]
    if len(output_names) == 1:
        if isinstance(x_weight, list) and len(x_weight) == 1:
            return x_weight
        if isinstance(x_weight, dict) and output_names[0] in x_weight:
            return [x_weight[output_names[0]]]
        else:
            return [x_weight]
    if isinstance(x_weight, list):
        if len(x_weight) != len(output_names):
            raise ValueError('Provided `' + weight_type +
                '` was a list of ' + str(len(x_weight)) +
                ' elements, but the model has ' + str(len(output_names)) +
                ' outputs. You should provide one `' + weight_type +
                '`array per model output.')
        return x_weight
    if isinstance(x_weight, dict):
        x_weights = []
        for name in output_names:
            x_weights.append(x_weight.get(name))
        return x_weights
    else:
        raise TypeError('The model has multiple outputs, so `' +
            weight_type + '` should be either a list or a dict. Provided `' +
            weight_type + '` type not understood: ' + str(x_weight))


def attachment_added(attachment):
    """Called when an attachment is added."""


@classmethod
def as_dict_static(cls, state_obj):
    """Method to return a dict representation of the object.
        Static method to be called from outside the class.

        :param state_obj: a namedtuple or an instance of this class

        :rtype: dict
        """
    keys = ['evalue', 'bits', 'global_identity', 'global_positives',
        'query_start', 'query_end', 'target_start', 'target_end',
        'hit_number', 'query_multiplier', 'target_multiplier',
        'query_aligned_length', 'target_aligned_length']
    state = dict().fromkeys(keys)
    for key in keys:
        state[key] = getattr(state_obj, key)
    return state


def check_test_runner():
    """
    Checks if the user has *not* overridden the ``TEST_RUNNER`` setting &
    warns them about the default behavior changes.

    If the user has overridden that setting, we presume they know what they're
    doing & avoid generating a message.
    """
    from django.conf import settings
    new_default = 'django.test.runner.DiscoverRunner'
    test_runner_setting = getattr(settings, 'TEST_RUNNER', new_default)
    if test_runner_setting == new_default:
        message = ["You have not explicitly set 'TEST_RUNNER'. In Django 1.6,",
            "there is a new test runner ('%s')" % new_default,
            'by default. You should ensure your tests are still all',
            'running & behaving as expected. See',
            'https://docs.djangoproject.com/en/dev/releases/1.6/#discovery-of-tests-in-any-test-module'
            , 'for more information.']
        return ' '.join(message)


@staticmethod
def get_quota_quota_command(text, folder):
    """
        Extract the quota from the quota command.

        Arguments:
        text - Text returned by quota command.
        folder - Mounted folder

        Return:
        None
        """
    write_value = False
    value_line = None
    for line in text:
        if write_value:
            value_line = line
            write_value = False
        else:
            pass
        if '{0}/'.format(folder.split('/')[0]) in line:
            write_value = True
        else:
            pass
    if value_line is None:
        raise KeyError
    size_list = []
    for value in value_line.split()[:2]:
        unit = value[-1]
        try:
            int(unit)
        except ValueError:
            size = value[:-1]
            if unit.startswith('M'):
                adjust = 1024 ** 2
            elif unit.startswith('G'):
                adjust = 1024
            elif unit.startswith('T'):
                adjust = 1
            elif unit.startswith('P'):
                adjust = 1 / 1024
            else:
                print(unit, 'unit of quota command not known!')
                print(
                    'Please contact the author of TranSPHIRE to fix this issue'
                    )
                raise KeyError
        else:
            adjust = 1024 ** 3
            size = value
        size_list.append(float(size) / adjust)
    return size_list[0], size_list[1]


def __new__(cls, visibilities_1d, *args, **kwargs):
    """ A hyper array with square-pixels.

        Parameters
        ----------
        array_1d: ndarray
            An array representing image (e.g. an image, noise map, etc.)
        pixel_scales: (float, float)
            The arc-second to pixel conversion factor of each pixel.
        origin : (float, float)
            The arc-second origin of the hyper array's coordinate system.
        """
    obj = visibilities_1d.view(cls)
    return obj


def show_rules_tab():
    """Determine whether or not the rules tab should be shown.
        """


def clamp(x, lower=float('-inf'), upper=float('inf')):
    """Limit a value to a given range.

    Args:
        x (int or float): Number to be clamped.
        lower (int or float): Minimum value for x.
        upper (int or float): Maximum value for x.

    The returned value is guaranteed to be between *lower* and
    *upper*. Integers, floats, and other comparable types can be
    mixed.

    >>> clamp(1.0, 0, 5)
    1.0
    >>> clamp(-1.0, 0, 5)
    0
    >>> clamp(101.0, 0, 5)
    5
    >>> clamp(123, upper=5)
    5

    Similar to `numpy's clip`_ function.

    .. _numpy's clip: http://docs.scipy.org/doc/numpy/reference/generated/numpy.clip.html

    """
    if upper < lower:
        raise ValueError('expected upper bound (%r) >= lower bound (%r)' %
            (upper, lower))
    return min(max(x, lower), upper)


def set_dtype(dtype):
    """Set the  dtype to use during estimation.

    Parameters
    ----------
    dtype : object
        numpy dtype
    """
    global _DTYPE
    _DTYPE = dtype


def is_ltdict(obj):
    """
        ltd = {0:1,1:2,2:3}
        is_ltdict(ltd) == True
        ltd = {0:1,2:2,3:3}
        is_ltdict(ltd) == False
        ltd = {0:1,'1':2,2:3}
        is_ltdict(ltd) == False
    """
    if isinstance(obj, dict):
        pass
    else:
        return False
    index_set = set({})
    if obj == {}:
        return True
    else:
        for key in obj:
            if isinstance(key, int):
                if key >= 0:
                    index_set.add(key)
                else:
                    return False
            else:
                return False
        for i in range(0, obj.__len__()):
            if i in index_set:
                pass
            else:
                return False
        return True


def calcByteSize(nBytes, formLang=False):
    """
    Return a given no. of Bytes in a human readable format.
    """
    sz = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
    szl = ['Byte', 'Kilobyte', 'Megabyte', 'Gigabyte', 'Terabyte',
        'Petabyte', 'Exabyte', 'Zettabyte', 'Yottabyte']
    i = 0
    neg = False
    if nBytes < 0:
        neg = True
        nBytes *= -1
    while nBytes > 1023:
        nBytes = nBytes / 1024
        i = i + 1
    if neg:
        nBytes *= -1
    if formLang:
        return '{0:.2f} {1:>3}'.format(nBytes, szl[i])
    else:
        return '{0:.2f} {1:>3}'.format(nBytes, sz[i])


def Almedeij(Re):
    """Calculates drag coefficient of a smooth sphere using the method in
    [1]_ as described in [2]_.

    .. math::
        C_D = \\left[\\frac{1}{(\\phi_1 + \\phi_2)^{-1} + (\\phi_3)^{-1}} + \\phi_4\\right]^{0.1}

    .. math::
        \\phi_1 = (24Re^{-1})^{10} + (21Re^{-0.67})^{10} + (4Re^{-0.33})^{10} + 0.4^{10}

    .. math::
        \\phi_2 = \\left[(0.148Re^{0.11})^{-10} + (0.5)^{-10}\\right]^{-1}

    .. math::
        \\phi_3 = (1.57\\times10^8Re^{-1.625})^{10}

    .. math::
        \\phi_4 = \\left[(6\\times10^{-17}Re^{2.63})^{-10} + (0.2)^{-10}\\right]^{-1}

    Parameters
    ----------
    Re : float
        Particle Reynolds number of the sphere using the surrounding fluid
        density and viscosity, [-]

    Returns
    -------
    Cd : float
        Drag coefficient [-]

    Notes
    -----
    Range is Re <= 1E6.
    Original work has been reviewed.

    Examples
    --------
    >>> Almedeij(200.)
    0.7114768646813396

    References
    ----------
    .. [1] Almedeij, Jaber. "Drag Coefficient of Flow around a Sphere: Matching
       Asymptotically the Wide Trend." Powder Technology 186, no. 3
       (September 10, 2008): 218-23. doi:10.1016/j.powtec.2007.12.006.
    .. [2] Barati, Reza, Seyed Ali Akbar Salehi Neyshabouri, and Goodarz
       Ahmadi. "Development of Empirical Models with High Accuracy for
       Estimation of Drag Coefficient of Flow around a Smooth Sphere: An
       Evolutionary Approach." Powder Technology 257 (May 2014): 11-19.
       doi:10.1016/j.powtec.2014.02.045.
    """
    phi4 = ((6e-17 * Re ** 2.63) ** -10 + 0.2 ** -10) ** -1
    phi3 = (157000000.0 * Re ** -1.625) ** 10
    phi2 = ((0.148 * Re ** 0.11) ** -10 + 0.5 ** -10) ** -1
    phi1 = (24 * Re ** -1) ** 10 + (21 * Re ** -0.67) ** 10 + (4 * Re ** -0.33
        ) ** 10 + 0.4 ** 10
    return (1 / ((phi1 + phi2) ** -1 + phi3 ** -1) + phi4) ** 0.1


@classmethod
def create_spec_from_sys_environ(cls, sys_environ):
    """Check system env for credentials and return a spec if present."""
    return {'available': False, 'message': 'Skipped. No credentials found.'}


def _update_source(cnx, cwsource):
    """Update cw_source relation of entities to point to Eurovoc CWSource.
    """
    sql = cnx.system_sql
    sqlqs = (
        "UPDATE cw_source_relation SET eid_to=%(source)s WHERE eid_from in (SELECT _X.cw_eid FROM cw_{0} AS _X WHERE _X.cw_cwuri ILIKE '%%eurovoc%%')"
        )
    for tablename in ('Label', 'Concept', 'ConceptScheme'):
        sql(sqlqs.format(tablename), {'source': cwsource.eid})
    cnx.commit()


def spectrum_to_xyz(spec_intens, temp):
    """
    Calculate the CIE X, Y, and Z coordinates corresponding to
    a light source with spectral distribution given by  the
    function SPEC_INTENS, which is called with a series of
    wavelengths between 380 and 780 nm (the argument is
    expressed in meters), which returns emittance at  that
    wavelength in arbitrary units.  The chromaticity
    coordinates of the spectrum are returned in the x, y, and z
    arguments which respect the identity:

            x + y + z = 1.

    CIE colour matching functions xBar, yBar, and zBar for
       wavelengths from 380 through 780 nanometers, every 5
       nanometers.  For a wavelength lambda in this range:

            cie_colour_match[(lambda - 380) / 5][0] = xBar
            cie_colour_match[(lambda - 380) / 5][1] = yBar
            cie_colour_match[(lambda - 380) / 5][2] = zBar

    AH Note 2011: This next bit is kind of irrelevant on modern
    hardware. Unless you are desperate for speed.
    In which case don't use the Python version!

    To save memory, this table can be declared as floats
    rather than doubles; (IEEE) float has enough
    significant bits to represent the values. It's declared
    as a double here to avoid warnings about "conversion
    between floating-point types" from certain persnickety
    compilers. */
    """
    cie_colour_match = [[0.0014, 0.0, 0.0065], [0.0022, 0.0001, 0.0105], [
        0.0042, 0.0001, 0.0201], [0.0076, 0.0002, 0.0362], [0.0143, 0.0004,
        0.0679], [0.0232, 0.0006, 0.1102], [0.0435, 0.0012, 0.2074], [
        0.0776, 0.0022, 0.3713], [0.1344, 0.004, 0.6456], [0.2148, 0.0073,
        1.0391], [0.2839, 0.0116, 1.3856], [0.3285, 0.0168, 1.623], [0.3483,
        0.023, 1.7471], [0.3481, 0.0298, 1.7826], [0.3362, 0.038, 1.7721],
        [0.3187, 0.048, 1.7441], [0.2908, 0.06, 1.6692], [0.2511, 0.0739,
        1.5281], [0.1954, 0.091, 1.2876], [0.1421, 0.1126, 1.0419], [0.0956,
        0.139, 0.813], [0.058, 0.1693, 0.6162], [0.032, 0.208, 0.4652], [
        0.0147, 0.2586, 0.3533], [0.0049, 0.323, 0.272], [0.0024, 0.4073,
        0.2123], [0.0093, 0.503, 0.1582], [0.0291, 0.6082, 0.1117], [0.0633,
        0.71, 0.0782], [0.1096, 0.7932, 0.0573], [0.1655, 0.862, 0.0422], [
        0.2257, 0.9149, 0.0298], [0.2904, 0.954, 0.0203], [0.3597, 0.9803,
        0.0134], [0.4334, 0.995, 0.0087], [0.5121, 1.0, 0.0057], [0.5945,
        0.995, 0.0039], [0.6784, 0.9786, 0.0027], [0.7621, 0.952, 0.0021],
        [0.8425, 0.9154, 0.0018], [0.9163, 0.87, 0.0017], [0.9786, 0.8163,
        0.0014], [1.0263, 0.757, 0.0011], [1.0567, 0.6949, 0.001], [1.0622,
        0.631, 0.0008], [1.0456, 0.5668, 0.0006], [1.0026, 0.503, 0.0003],
        [0.9384, 0.4412, 0.0002], [0.8544, 0.381, 0.0002], [0.7514, 0.321,
        0.0001], [0.6424, 0.265, 0.0], [0.5419, 0.217, 0.0], [0.4479, 0.175,
        0.0], [0.3608, 0.1382, 0.0], [0.2835, 0.107, 0.0], [0.2187, 0.0816,
        0.0], [0.1649, 0.061, 0.0], [0.1212, 0.0446, 0.0], [0.0874, 0.032,
        0.0], [0.0636, 0.0232, 0.0], [0.0468, 0.017, 0.0], [0.0329, 0.0119,
        0.0], [0.0227, 0.0082, 0.0], [0.0158, 0.0057, 0.0], [0.0114, 0.0041,
        0.0], [0.0081, 0.0029, 0.0], [0.0058, 0.0021, 0.0], [0.0041, 0.0015,
        0.0], [0.0029, 0.001, 0.0], [0.002, 0.0007, 0.0], [0.0014, 0.0005,
        0.0], [0.001, 0.0004, 0.0], [0.0007, 0.0002, 0.0], [0.0005, 0.0002,
        0.0], [0.0003, 0.0001, 0.0], [0.0002, 0.0001, 0.0], [0.0002, 0.0001,
        0.0], [0.0001, 0.0, 0.0], [0.0001, 0.0, 0.0], [0.0001, 0.0, 0.0], [
        0.0, 0.0, 0.0]]
    X = 0
    Y = 0
    Z = 0
    for i, lamb in enumerate(range(380, 780, 5)):
        Me = spec_intens(lamb, temp)
        X += Me * cie_colour_match[i][0]
        Y += Me * cie_colour_match[i][1]
        Z += Me * cie_colour_match[i][2]
    XYZ = X + Y + Z
    x = X / XYZ
    y = Y / XYZ
    z = Z / XYZ
    return x, y, z


def split_string(param_string):
    """
    Splits a comma separated list of rx,ry,rz,tx,ty,tz to a list of floats.
    :param param_string: string
    :return: list of float
    """
    result = [0, 0, 0, 0, 0, 0]
    if param_string is not None:
        split = param_string.split(',')
        if len(split) != 6:
            raise ValueError('List is wrong length:' + str(split))
        for i in range(6):
            result[i] = float(split[i])
    return result


def KK_RC19(w, Rs, R_values, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    return Rs + R_values[0] / (1 + w * 1.0j * t_values[0]) + R_values[1] / (
        1 + w * 1.0j * t_values[1]) + R_values[2] / (1 + w * 1.0j * t_values[2]
        ) + R_values[3] / (1 + w * 1.0j * t_values[3]) + R_values[4] / (1 +
        w * 1.0j * t_values[4]) + R_values[5] / (1 + w * 1.0j * t_values[5]
        ) + R_values[6] / (1 + w * 1.0j * t_values[6]) + R_values[7] / (1 +
        w * 1.0j * t_values[7]) + R_values[8] / (1 + w * 1.0j * t_values[8]
        ) + R_values[9] / (1 + w * 1.0j * t_values[9]) + R_values[10] / (1 +
        w * 1.0j * t_values[10]) + R_values[11] / (1 + w * 1.0j * t_values[11]
        ) + R_values[12] / (1 + w * 1.0j * t_values[12]) + R_values[13] / (
        1 + w * 1.0j * t_values[13]) + R_values[14] / (1 + w * 1.0j *
        t_values[14]) + R_values[15] / (1 + w * 1.0j * t_values[15]
        ) + R_values[16] / (1 + w * 1.0j * t_values[16]) + R_values[17] / (
        1 + w * 1.0j * t_values[17]) + R_values[18] / (1 + w * 1.0j *
        t_values[18])


def compute_F1(precision, recall):
    """ Compute F1 score """
    return 2 * recall * precision / (recall + precision)


def _merge_prefix(deque, size):
    """Replace the first entries in a deque of strings with a single
    string of up to size bytes.

    >>> d = collections.deque(['abc', 'de', 'fghi', 'j'])
    >>> _merge_prefix(d, 5); print(d)
    deque(['abcde', 'fghi', 'j'])

    Strings will be split as necessary to reach the desired size.
    >>> _merge_prefix(d, 7); print(d)
    deque(['abcdefg', 'hi', 'j'])

    >>> _merge_prefix(d, 3); print(d)
    deque(['abc', 'defg', 'hi', 'j'])

    >>> _merge_prefix(d, 100); print(d)
    deque(['abcdefghij'])
    """
    if len(deque) == 1 and len(deque[0]) <= size:
        return
    prefix = []
    remaining = size
    while deque and remaining > 0:
        chunk = deque.popleft()
        if len(chunk) > remaining:
            deque.appendleft(chunk[remaining:])
            chunk = chunk[:remaining]
        prefix.append(chunk)
        remaining -= len(chunk)
    if prefix:
        deque.appendleft(type(prefix[0])().join(prefix))
    if not deque:
        deque.appendleft(b'')


def get_post_fields(request):
    """parse through a request, and return fields from post in a dictionary

       Parameters
       ==========
       request: a request object
    """
    fields = dict()
    for field, value in request.form.items():
        fields[field] = value
    return fields


def tmy_hdd_cdd(t_dry, hdd_threshold=13, hdd_ref=18, cdd_threshold=26,
    cdd_ref=24):
    """
    from TMY temp calculate heating (hdd) and cooling degree-days (cdd)

    from a TMY list with 8760 hourly values for temperature calculate
    the heating degree-days (hdd) and the cooling degree-days (cdd)

    calculation principle: iterate over all days of the year, consider
    only those days with average temperature equal or below the temperature
    hdd_threshold (equal or above cdd_threshold for cooling DD).
    Add up in the heat_degree_days the absolute difference of the average
    temperature for the considered day and the reference temperature hdd_ref.
    The procedure is similar for cooling DD, with the absolute difference
    between the average day temperature and the cdd reference.
    Return the total.

    The formula considers that heating is necessary for those days with
    average temperature below the threshold (or above the other threshold
    in the case of cooling). Heating must be provided to bring the indoors
    temperature to hdd_ref, or cooling to bring the temperature down to
    cdd_ref.

    input data:
    - list with 8760 temperature values
    - threshold temperature for hdd addition yes/no (default value: 13C)
    - reference temperature for hdd calculation (default value: 18C)
    - threshold temperature for cdd addition yes/no (default value: 26C)
    - reference temperature for cdd calculation (default value: 24C)

    all values integer or float

    output:
    tuple with
    - heating degree days, integer
    - cooling degree days, integer

    """
    heat_ddays = 0
    cool_ddays = 0
    if hdd_threshold < hdd_ref and cdd_threshold > cdd_ref:
        for d in range(0, 365):
            day_temp = 0
            for h in range(0, 24):
                h_idx = d * 24 + h
                day_temp = day_temp + t_dry[h_idx]
            day_temp_avg = day_temp / 24
            if day_temp_avg <= hdd_threshold:
                heat_ddays = heat_ddays + (hdd_ref - day_temp_avg)
            if day_temp_avg >= cdd_threshold:
                cool_ddays = cool_ddays + (day_temp_avg - cdd_ref)
    return int(round(heat_ddays, 0)), int(round(cool_ddays, 0))


def success_response(body):
    """ Defines a success response structure """
    return {'status': 'OK', 'body': body}


def get(cls, name):
    """Return a registred subclass by it's __id."""
    return cls._registry.get(name)


def get_fd(file_or_fd, default=None):
    """Helper function for getting a file descriptor."""
    fd = file_or_fd
    if fd is None:
        fd = default
    if hasattr(fd, 'fileno'):
        fd = fd.fileno()
    return fd


def join(tokens):
    """ construct a string sentence from joining tokens with spaces
    args:
        tokens: list of strings
    returns:
        joined_tokens: a string containing all tokens
    """
    joined_tokens = ' '.join(tokens)
    return joined_tokens


def getTTL():
    """
        Get time to live for multicast packets.
        """


def check_images(images):
    """ Validates the data received via ajax

    First it checks to see if the data can be converted to a python object.

    Then it checks to see if it is a list of (str, int) tuples

    Arguments:
    :param images: a supposed string representation of list of (str, int)
    tuples
    :type images: str
    :returns None or a list
    """
    from ast import literal_eval
    try:
        images = literal_eval(images)
    except:
        return None
    if isinstance(images, list) and len(images) > 0:
        for image in images:
            if isinstance(image, tuple) and len(image) == 2 and isinstance(
                image[0], str) and isinstance(image[1], int):
                continue
            else:
                return None
        return images
    else:
        return None


def aggregate_info(infoextractors):
    """
    Aggregates inforamtion extracted from multiple ``InfoExtractor``
    instances to one dictionary.

    :param infoextractors: list of values of ``information`` attribute
                           of different ``InfoExtractor`` instances.
    """
    result = {}
    for ie in infoextractors:
        for fname, extracted_info in ie.items():
            for info_name, info_instances in extracted_info.items():
                if result.get(info_name):
                    result[info_name] += info_instances
                else:
                    result[info_name] = info_instances
    return result


@classmethod
def canClearBrowserCache(cls):
    """Tells whether clearing browser cache is supported.
        """
    return cls.build_send_payload('canClearBrowserCache', {}
        ), cls.convert_payload({'result': {'class': bool, 'optional': False}})


def unique(input):
    """Returns the unique scalar elements in a tensor.

    Parameters
    ----------
    input : Tensor
        Must be a 1-D tensor.

    Returns
    -------
    Tensor
        A 1-D tensor containing unique elements.
    """
    pass


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 format_seconds(seconds: int):
    """
        Formats an amount of seconds into a mm:ss format. If in hour-range, also add hours in front (h:mm:ss)

        :param seconds: amount of seconds to be formatted
        :type seconds: int
        :return: string in h:mm:ss format.
        """
    result = ''
    if seconds // 3600 > 0:
        result += f'{seconds // 3600}:'
    result += (
        f'{str(seconds % 3600 // 60).zfill(2)}:{str(seconds % 60).zfill(2)}')
    return result


def CopyBand(srcband, dstband):
    """
	from http://www.mit.edu/afs.new/athena/software/fwtools/current/FWTools-linux-i686-3.1.0/usr/bin/gdal_fillnodata.py
	"""
    for line in range(srcband.YSize):
        line_data = srcband.ReadRaster(0, line, srcband.XSize, 1)
        dstband.WriteRaster(0, line, srcband.XSize, 1, line_data, buf_type=
            srcband.DataType)


@staticmethod
def _validate_num_actions(num_actions):
    """Return num_actions if valid. Otherwise raise ValueError.

        Return
        ------
        int
            Number of possible actions.

        Raises
        ------
        ValueError
            If num_actions < 1

        """
    if num_actions < 1:
        raise ValueError('num_actions must be >= 1')
    return num_actions


def getInvertedDictionary(dict, make_unique=False):
    """returns an inverted dictionary with keys and values swapped.
    """
    inv = {}
    if make_unique:
        for k, v in dict.items():
            inv[v] = k
    else:
        for k, v in dict.items():
            inv.setdefault(v, []).append(k)
    return inv


@classmethod
def genprefix(cls, node, ns):
    """
        Generate a prefix.
        @param node: An XML node on which the prefix will be used.
        @type node: L{sax.element.Element}
        @param ns: A namespace needing an unique prefix.
        @type ns: (prefix, uri)
        @return: The I{ns} with a new prefix.
        """
    for n in range(1, 1024):
        p = 'ns%d' % n
        u = node.resolvePrefix(p, default=None)
        if u is None or u == ns[1]:
            return p, ns[1]
    raise Exception('auto prefix, exhausted')


def make_shorthand(intrinsic_dict):
    """
    Converts a given intrinsics dictionary into a short-hand notation that Fn::Sub can use. Only Ref and Fn::GetAtt
    support shorthands.
    Ex:
     {"Ref": "foo"} => ${foo}
     {"Fn::GetAtt": ["bar", "Arn"]} => ${bar.Arn}

    This method assumes that the input is a valid intrinsic function dictionary. It does no validity on the input.

    :param dict intrinsic_dict: Input dictionary which is assumed to be a valid intrinsic function dictionary
    :returns string: String representing the shorthand notation
    :raises NotImplementedError: For intrinsic functions that don't support shorthands.
    """
    if 'Ref' in intrinsic_dict:
        return '${%s}' % intrinsic_dict['Ref']
    elif 'Fn::GetAtt' in intrinsic_dict:
        return '${%s}' % '.'.join(intrinsic_dict['Fn::GetAtt'])
    else:
        raise NotImplementedError(
            'Shorthanding is only supported for Ref and Fn::GetAtt')


def ordered_dict_representer(dumper, data):
    """OrderedDict representer"""
    return dumper.represent_mapping('tag:yaml.org,2002:map', data.items())


def capable(name):
    """Determine support for a named capability.

        Returns ``False`` if capability not supported.

        Returns ``True`` if boolean capability is supported. Returns a string
        if capability support is non-boolean.

        Capability strings may or may not map to wire protocol capabilities.
        """


def _shuffle(data=None, name=None, attr=None, out=None, **kwargs):
    """Randomly shuffle the elements.

    This shuffles the array along the first axis.
    The order of the elements in each subarray does not change.
    For example, if a 2D array is given, the order of the rows randomly changes,
    but the order of the elements in each row does not change.

    Parameters
    ----------
    data : Symbol
        Data to be shuffled.

    name : string, optional.
        Name of the resulting symbol.

    Returns
    -------
    Symbol
        The result symbol.
    """
    return 0,


def _join(segments):
    """simply list by joining adjacent segments."""
    new = []
    start = segments[0][0]
    end = segments[0][1]
    for i in range(len(segments) - 1):
        if segments[i + 1][0] != segments[i][1]:
            new.append((start, end))
            start = segments[i + 1][0]
        end = segments[i + 1][1]
    new.append((start, end))
    return new


def subdict(d, *keys, key_filter=lambda o: o, value_filter=lambda o: o):
    """Return Subdictionary"""
    keys = set(d.keys()) - set(keys)
    out = {}
    for k in filter(key_filter, keys):
        value = d[k]
        if value_filter(value):
            out[k] = value
    return out


def get_in(obj, keys):
    """
    >>> get_in({'a': {'b': 1}}, 'a.b')
    1
    """
    if isinstance(keys, str):
        keys = keys.split('.')
    for key in keys:
        if not obj or key not in obj:
            return None
        obj = obj[key]
    return obj


def distributed_configuration():
    """Returns the DistributedConfiguration object from the Manager

    """
    from .managers import Manager
    return Manager().get_DistributedConfiguration()


def multi_char_literal(chars):
    """Emulates character integer literals in C. Given a string "abc",
    returns the value of the C single-quoted literal 'abc'.
    """
    num = 0
    for index, char in enumerate(chars):
        shift = (len(chars) - index - 1) * 8
        num |= ord(char) << shift
    return num


def bitflags(*args):
    """Take a sequence of bool values and return an integer with those bits set."""
    cur, val = 1, 0
    for arg in args:
        if arg:
            val |= cur
        cur <<= 1
    return val


def traverse(name, furtherPath):
    """Get the next item on the path

        Should return the item corresponding to 'name' or raise
        :exc:`~zope.location.interfaces.LocationError` where appropriate.

        :param str name: an ASCII string or Unicode object.
        :param list furtherPath: is a list of names still to be
            traversed.  This method is allowed to change the contents
            of furtherPath.
        """


@classmethod
def map_head_object_params(cls, request_params, cli_params):
    """Map CLI params to HeadObject request params"""
    cls._set_sse_c_request_params(request_params, cli_params)
    cls._set_request_payer_param(request_params, cli_params)


@classmethod
def set_engine_reference(cls, class_ref):
    """
        Set the reference of engine class to this class
        :param class_ref: The reference to engine class
        """
    cls.engine = class_ref


def _stacktrace_beginning(stacktrace, size):
    """ Gets the first `size` bytes of the stacktrace """
    if len(stacktrace) <= size:
        return stacktrace
    return stacktrace[:size]


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

        :param ShowcaseRenamedDetails val:
        :rtype: EventDetails
        """
    return cls('showcase_renamed_details', val)


def next():
    """Iterator protocol. See Python documentation for :class:`io.IOBase` for
        details.
        """


def validate_file(file):
    """
    Valida que una variable refiera a una instancia de un archivo.

    :file: [any] - Elemento a validar

    :return: [Boolean] - True si es una instancia de archivo, False en caso contrario
    """
    return hasattr(file, 'read')


def continuous_ls(ls):
    """Tries to convert Ls values to be continuous.
    Does this by looking for negative changes in Ls values and assumes that's the next year of data"""
    loop = -1
    old = 360.0
    for i, v in enumerate(ls):
        if v < old + 1e-05:
            loop += 1
        ls[i] += loop * 360.0
        old = v
    return ls


def add(config, name, spec, **extra):
    """ Add a new static info registration """


def convert_extension(filename, extensions=('yaml', 'yml')):
    """
    Convert YeT extension in filename to .tex

    :param filename: string of file name. validity not checked.
    :param extensions: tuple of extensions (without dot) to treat as YeT
    """
    if '.' in filename:
        ext = filename.split('.')[-1]
        if ext in extensions:
            idx = filename.rindex('.')
            return f'{filename[:idx]}.tex'
    return f'{filename}.tex'


def _sessions_and_keywords_merge_func(key, command_args, noxfile_args):
    """Only return the Noxfile value for sessions/keywords if neither sessions
    or keywords are specified on the command-line.

    Args:
        key (str): This function is used for both the "sessions" and "keywords"
            options, this allows using ``funtools.partial`` to pass the
            same function for both options.
        command_args (_option_set.Namespace): The options specified on the
            command-line.
        noxfile_Args (_option_set.Namespace): The options specified in the
            Noxfile."""
    if not command_args.sessions and not command_args.keywords:
        return getattr(noxfile_args, key)
    return getattr(command_args, key)


def stub_dict():
    """Returns empty "dict".

    Returns:
        dict: Empty dict.

    Example:

        >>> stub_dict()
        {}

    .. versionadded:: 4.0.0
    """
    return {}


def clear():
    """
	Deletes all stored variables
	"""
    with open('var_list.silas', 'r+') as var_list:
        var_list.truncate(0)
        var_list.close


@classmethod
def _id_from_data(cls, data):
    """
        Extract stripe id from stripe field data
        :param data:
        :return:
        """
    if isinstance(data, str):
        id_ = data
    elif data:
        id_ = data.get('id')
    else:
        id_ = None
    return id_


def check_unified_length(data):
    """
    check nested list data have same length

    :param data: list
    :return: bool
    """
    assert isinstance(data, list)
    length_list = map(len, data)
    if len(set(length_list)) == 1:
        return True
    else:
        return False


def round_updown_to_x(num_in, x, direction='up'):
    """
    Rounds a given value (num_in) to the nearest multiple of x, in a given
    direction (up or down)
    :param num_in: Input value
    :param x: Value to round to a multiple of
    :param direction: Round up or down. Default: 'up'
    :return: Rounded number
    """
    if direction is 'down':
        num_out = int(num_in) - int(num_in) % int(x)
    else:
        num_out = num_in + (x - num_in) % int(x)
    return num_out


def transduce(transformer, reducer, seed, iterable):
    """
    transformer is (a -> b)
    reducer is (b -> a -> b)
    seed is b
    iterable is [a]
    """
    transformedReducer = transformer(reducer)
    accumulation = seed
    for value in iterable:
        accumulation = transformedReducer(accumulation, value)
    return accumulation


def is_cuda_ndarray(obj):
    """Check if an object is a CUDA ndarray"""
    return getattr(obj, '__cuda_ndarray__', False)


def process_choice_data(dict_, data):
    """This functions processes the inputs for the
    decision equation"""
    indicator = dict_['ESTIMATION']['indicator']
    D = data[indicator].values
    Z = data[dict_['CHOICE']['order']]
    return indicator, D, Z


def is_number(number_str):
    """Test if number_str is number including infraformat logic."""
    try:
        complex(number_str)
    except ValueError:
        if number_str == '-':
            return True
        return False
    return True


def pa_to_feast_value_attr(pa_type: object):
    """
    Returns the equivalent Feast ValueType string for the given pa.lib type.

    Args:
        pa_type (object):
            PyArrow type.

    Returns:
        str:
            Feast attribute name in Feast ValueType string-ed representation.
    """
    type_map = {'timestamp[ms]': 'int64_val', 'int32': 'int32_val', 'int64':
        'int64_val', 'double': 'double_val', 'float': 'float_val', 'string':
        'string_val', 'binary': 'bytes_val', 'bool': 'bool_val',
        'list<item: int32>': 'int32_list_val', 'list<item: int64>':
        'int64_list_val', 'list<item: double>': 'double_list_val',
        'list<item: float>': 'float_list_val', 'list<item: string>':
        'string_list_val', 'list<item: binary>': 'bytes_list_val',
        'list<item: bool>': 'bool_list_val'}
    return type_map[pa_type.__str__()]


def edge_labels(graph, edge_label_attr='weight'):
    """
    Utility function that aggreates node attributes as
    labels for drawing graph in Ipython Notebook.

    :param graph: networkx.Graph
    :returns: Dict. Nodes as keys, labels as values.
    """
    labels_dict = {}
    for i, j, attrs in graph.edges(data=True):
        label = attrs.get(edge_label_attr, '')
        labels_dict[i, j] = label
    return labels_dict


def literally(obj):
    """Forces Numba to interpret *obj* as an Literal value.

    *obj* must be either a literal or an argument of the caller function, where
    the argument must be bound to a literal. The literal requirement
    propagates up the call stack.

    This function is intercepted by the compiler to alter the compilation
    behavior to wrap the corresponding function parameters as ``Literal``.
    It has **no effect** outside of nopython-mode (interpreter, and objectmode).

    The current implementation detects literal arguments in two ways:

    1. Scans for uses of ``literally`` via a compiler pass.
    2. ``literally`` is overloaded to raise ``numba.errors.ForceLiteralArg``
       to signal the dispatcher to treat the corresponding parameter
       differently. This mode is to support indirect use (via a function call).

    The execution semantic of this function is equivalent to an identity
    function.

    See :ghfile:`numba/tests/test_literal_dispatch.py` for examples.
    """
    return obj


def heads():
    """Determine all known head revisions in the peer.

        Returns an iterable of binary nodes.
        """


def reindex_df(subdomain_df):
    """Reindex subdomain dataframe and starts at indice 1."""
    subdomain_df.drop_duplicates(inplace=True)
    subdomain_df.reset_index(drop=True, inplace=True)
    subdomain_df.index += 1
    return subdomain_df


def set_right(stereo_samp, v):
    """Set StereoSample stereo_samp's right value to v."""
    stereo_samp.set_right(v)


def _len_list(obj):
    """Length of list (estimate).
    """
    n = len(obj)
    if n > 8:
        n += 6 + (n >> 3)
    elif n:
        n += 4
    return n


def getConfigurationOptions():
    """
        Retrieve all known node configuration options.

        The returned dictionary holds the possible node configuration options
        by option name. The value of each entry represents the specifics for
        that option in a dictionary:

         - C{'type'} (C{str}): The option's type (see
           L{Field<wokkel.data_form.Field>}'s doc string for possible values).
         - C{'label'} (C{unicode}): A human readable label for this option.
         - C{'options'} (C{dict}): Optional list of possible values for this
           option.

        Example::

            {
            "pubsub#persist_items":
                {"type": "boolean",
                 "label": "Persist items to storage"},
            "pubsub#deliver_payloads":
                {"type": "boolean",
                 "label": "Deliver payloads with event notifications"},
            "pubsub#send_last_published_item":
                {"type": "list-single",
                 "label": "When to send the last published item",
                 "options": {
                     "never": "Never",
                     "on_sub": "When a new subscription is processed"}
                }
            }

        @rtype: C{dict}.
        """


def edge_iter(node, filter_fn=None):
    """
    Iterates over the child edge of `node` and all its descendants.
    Can optionally be filtered by `filter_fn`.
    """
    stack = list(node.child_edge_iter())
    while stack:
        edge = stack.pop()
        if filter_fn is None or filter_fn(edge):
            yield edge
        stack.extend(edge.head_node.child_edge_iter())


def get_all(isamAppliance, check_mode=False, force=False):
    """
    Retrieve a list of mapping rules
    """
    return isamAppliance.invoke_get('Retrieve a list of mapping rules',
        '/iam/access/v8/mapping-rules')


@classmethod
def search_or_abort(cls, *args, **kwargs):
    """
        Shortcut to ``SearchableDocument.searcher.search_or_abort``
        """
    return cls._search_bootstrap().search_or_abort(*args, **kwargs)


def sighandler_noop(signum, frame):
    """Signal handler doing nothing."""
    pass


def fprintf(opened_file, fmt, *args):
    """
    A helper function used to print to a specified file.
    :param opened_file: A file object that has already been opened using open()
    """
    opened_file.write(fmt % args)


def Setup():
    """
  Called when the code is installed.

  """
    raise NotImplementedError('This mission is not yet supported.')


def data(settings) ->str:
    """
    Impute name of field containing base64 encoded data.

    Parameters
    ----------
    settings : typing.Dict
        YAML parsed to dict

    Returns
    -------
    str:
        "name_of_data_field"
    """
    return '"' + settings['input']['name'] + '"'


def second(items):
    """
    Gets the second item from a collection.
    """
    return items[1]


def _create_hdf5_info(h5_file, op2_model):
    """exports the h5 info group"""
    load_as_h5 = False
    if hasattr(op2_model, 'load_as_h5'):
        load_as_h5 = op2_model.load_as_h5
    if not load_as_h5:
        return
    from pyNastran.op2.op2_interface.hdf5_interface import create_info_group
    create_info_group(h5_file, op2_model)


def vert_splice(vert: 'bmesh.types.BMVert', vert_target: 'bmesh.types.BMVert'):
    """Splice vert into vert_target.

    :param vert: The vertex to be removed.
    :type vert: 'bmesh.types.BMVert'
    :param vert_target: The vertex to use.
    :type vert_target: 'bmesh.types.BMVert'
    """
    pass


def p_power_star_1(p):
    """power_star : trailer"""
    p[0] = [p[1]]


def branchtip(repo, heads):
    """return the tipmost branch head in heads"""
    tip = heads[-1]
    for h in reversed(heads):
        if 'close' not in repo.changelog.read(h)[5]:
            tip = h
            break
    return tip


def median(items):
    """Returns the median value of the argument items.

    Args:
        items (iterable): a list of numeric values

    Returns:
        numeric: the median of the list if non-empty else None

    """
    items = sorted(items)
    if len(items) < 1:
        return None
    if len(items) % 2 == 1:
        return items[(len(items) + 1) / 2 - 1]
    if len(items) % 2 == 0:
        return float(sum(items[len(items) / 2 - 1:len(items) / 2 + 1])) / 2.0


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

    The ".dev0" means dirty.

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


def get_instance(dataset_id):
    """ Break dataset_id from ESGF search in dictionary of instance attributes """
    bits = dataset_id.split('.')
    if '|esgfcog' in bits[8]:
        return {'model': bits[3], 'experiment': bits[4], 'realm': bits[6],
            'ensemble': bits[7], 'version': bits[8].split('|')[0]}
    return {'model': bits[3], 'experiment': bits[4], 'realm': bits[6],
        'mip': bits[7], 'ensemble': bits[8], 'version': bits[9].split('|')[0]}


@classmethod
def list_datasets(cls):
    """Return a list of names of available datasets"""
    return sorted(cls._dataset_info.keys())


def UnsealAll(inst):
    """ Unseal all LocustEndpoint instances making them able to perform requests"""
    for instance in inst.BackpackPouch:
        instance.unseal


def psi_none(T, P):
    """i-i'-j: no interaction effect."""
    psi = 0
    valid = T > 0
    return psi, valid


def read_number(stream):
    """
    Reads a decimal number, returning value as string
    """
    start = stream.ptr
    while True:
        if not stream.text[stream.ptr].isdigit() and stream.text[stream.ptr
            ] != '.':
            break
        stream.ptr += 1
    return stream.text[start:stream.ptr]


def set_robust(robust):
    """Return generic name if user passes None to the robust parameter in a
    regression. Note: already verified that the name is valid in
    check_robust() if the user passed anything besides None to robust.

    Parameters
    ----------
    robust      : string or None
                  Object passed by the user to a regression class

    Returns
    -------
    robust      : string

    """
    if not robust:
        return 'unadjusted'
    return robust


@classmethod
def parse_carbon(cls, path):
    """parse a carbon path with optional tags: metric;tag=value;..."""
    segments = path.split(';')
    metric = segments[0]
    if not metric:
        raise Exception('Cannot parse path %s, no metric found' % path)
    tags = {}
    for segment in segments[1:]:
        tag = segment.split('=', 1)
        if len(tag) != 2 or not tag[0]:
            raise Exception('Cannot parse path %s, invalid segment %s' % (
                path, segment))
        cls.validateTagAndValue(*tag)
        tags[tag[0]] = tag[1]
    tags['name'] = cls.sanitize_name_as_tag_value(metric)
    return cls(metric, tags)


@staticmethod
def _translate(parsed_metadata):
    """
        Transforms the parsed metadata into a format suitable for writing to
        the mediachain network.
        :param parsed_metadata: a dict containing un-translated metadata
        :return: a dict containing mediachain records.

        e.g:
        {"object": {"type": "artefact", "meta": {}},
         "related": {
           "artefactCreatedBy": {
             "object": {"type": "entity", "meta": {}}
           }
         }
        }
        """
    raise NotImplementedError(
        'subclasses should return dictionary of translated metadata')


def unzscore(z, original_y):
    """change a zscore prediction back to dollars using original Series. Remember rolling!"""
    return z * original_y.std() + original_y.mean()


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 unregister(ob):
    """Remove the object from the indexes.

        IntIdMissingError is raised if ob is not registered previously.
        """


@staticmethod
def format_result(input):
    """From: http://stackoverflow.com/questions/13062300/convert-a-dict-to-sorted-dict-in-python
        """
    return list(input)


def zoom_in(zoomfacx: float=0.0, zoomfacy: float=0.0):
    """Zoom in the view

    :param zoomfacx: Zoom Factor X
    :type zoomfacx: float
    :param zoomfacy: Zoom Factor Y
    :type zoomfacy: float
    """
    pass


def _unary_compiler(tmpl):
    """Compiler factory for the `_Compiler`."""
    return lambda self, x: tmpl % self.compile(x)


@staticmethod
def strip_old_content(string):
    """
        Strip lines starting with - from given string.

        Args:
            string(str): String to remove lines from.

        Returns:
            str: String without the lines starting with -.
        """
    if string.startswith('+'):
        return string
    return ''


def set_backend(backend):
    """Method for setting the backend.

    Returns
    -------
    str
        The new backend as a string
    """
    global _BACKEND
    _BACKEND = str(backend)


def aerodynamical_resistance_soil(u_i_soil):
    """
    Computes the aerodynamical resistance of the soil

    .. math ::
        r_{a,s}=\\frac{1}{\\left(0.0025T_{dif}^{\\frac{1}{3}}+0.012u_{i,s}\\right)}

    Parameters
    ----------
    u_i_soil : float
        instantaneous wind speed just above soil surface
        :math:`u_{i,s}`
        [m s-1]

    Returns
    -------
    ras : float
        aerodynamical resistance
        :math:`r_{a,s}`
        [sm-1]

    """
    Tdif = 10.0
    return 1.0 / (0.0025 * Tdif ** (1.0 / 3.0) + 0.012 * u_i_soil)


def not_ok(option):
    """ treat None option as not OK """
    return option is None or not option.ok


@staticmethod
def get_catalog_file(config):
    """Get catalog file"""
    if config is not None:
        return config.get('file', 'poco-catalog.yml')
    return None


def sf_create_compose_application(client, compose_file, application_id,
    registry_user=None, registry_pass=None, encrypted=False, timeout=60):
    """
    Creates a Service Fabric application from a Compose file

    :param str application_id:  The id of application to create from
    Compose file. This is typically the full id of the application
    including "fabric:" URI scheme

    :param str compose_file: Path to the Compose file to use

    :param str registry_user: Username for target container registry

    :param bool encrypted: Indicates usage of encrypted password

    :param str registry_pass: Password for target container registry
    """
    from azure.cli.core.util import read_file_content
    from azure.cli.core.prompting import prompt
    from azure.cli.core.prompting import prompt_pass
    from azure.servicefabric.models.create_compose_application_description import CreateComposeApplicationDescription
    from azure.servicefabric.models.repository_credential import RepositoryCredential
    if not registry_user and registry_pass:
        registry_user = prompt('Registry username: ',
            'Username for target container registry')
    if not registry_pass and registry_user:
        registry_pass = prompt_pass('Registry password: ', False,
            'Password for target container registry')
    registry_cred = RepositoryCredential(registry_user, registry_pass,
        encrypted) if registry_user and registry_pass else None
    file_contents = read_file_content(compose_file)
    model = CreateComposeApplicationDescription(application_id,
        file_contents, registry_cred)
    client.create_compose_application(model, timeout)


@staticmethod
def AllInventoriesInt():
    """
        Get all inventory types as ints.

        Returns:
            list: of int formatted inventory types.
        """
    return [1, 2, 224]


def get_numpy_include_path():
    """
    Gets the path to the numpy headers.
    """
    import builtins
    if hasattr(builtins, '__NUMPY_SETUP__'):
        del builtins.__NUMPY_SETUP__
    import imp
    import numpy
    imp.reload(numpy)
    try:
        numpy_include = numpy.get_include()
    except AttributeError:
        numpy_include = numpy.get_numpy_include()
    return numpy_include


@staticmethod
def __add_filename_suffix(filename, suffix):
    """
        Add a suffix to a filename (before the extension).
        The suffix is extracted from the config file.
        :param filename: filename to add the suffix to
        :param suffix: suffix given to the compressed file (before the extension)
        :return: filename with suffix appended
        """
    return '{}{}.pdf'.format(filename.split('.pdf', 1)[0], suffix)


def parse_args():
    """Fetch args as dict from command

	Returns:
		A dict representing the system args.
		example:
		{'config': 0, 'begin': 0, 'path': ['./20123.xls'], 'end': 0}
	"""
    import argparse
    import sys
    if len(sys.argv) == 1:
        sys.argv.append('--help')
    parser = argparse.ArgumentParser()
    parser.add_argument('-b', '--begin', default=0, help=
        '需要导出记录的起始时间(和字段形式一致), 缺省为最早时间')
    parser.add_argument('-e', '--end', default=0, help=
        '需要导出记录的终止时间(和字段形式一致), 缺省为最新时间')
    parser.add_argument('-c', '--config', default=0, help=
        '配置文件路径(如: /home/user/aptexp.conf), 缺省为指定字段')
    parser.add_argument('path', metavar='PATH', nargs=1, help=
        '输出xls文件保存路径(如: /home/user/20180403.xls)')
    args = parser.parse_args()
    return vars(args)


@classmethod
def fromfile(cls, fh_ts, fh_raw, payload_nbytes=1 << 24, nchan=1, bps=4,
    complex_data=False, valid=True, verify=True):
    """Read a frame from timestamp and raw data filehandles.

        Any arguments beyond the filehandle are used to help initialize the
        payload, except for ``valid`` and ``verify``, which are passed on
        to the header and class initializers.

        Parameters
        ----------
        fh_ts : filehandle
            To the timestamp file.  The next line will be read.
        fh_raw : file_handle or tuple
            Should be a single handle for a rawdump data frame, or a tuple
            containing tuples with pairs of handles for a phased one.  E.g.,
            ``((L1, L2), (R1, R2))`` for left and right polarisations.
        payload_nbytes : int, optional
            Size of the individual payloads in bytes.  Default: ``2**24``
            (16 MB).
        nchan : int, optional
            Number of channels.  Default: 1.
        bps : int, optional
            Bits per elementary sample.  Default: 4.
        complex_data : bool, optional
            Whether data are complex.  Default: `False`.
        valid : bool, optional
            Whether the data are valid (default: `True`). Note that this cannot
            be inferred from the header or payload itself.  If `False`, any
            data read will be set to ``cls.fill_value``.
        verify : bool, optional
            Whether to verify consistency of the frame parts.  Default: `True`.
        """
    header = cls._header_class.fromfile(fh_ts, verify=verify)
    payload = cls._payload_class.fromfile(fh_raw, payload_nbytes=
        payload_nbytes, nchan=nchan, bps=bps, complex_data=complex_data)
    return cls(header, payload, valid=valid, verify=verify)


def setExpression(expression):
    """ Change the expression condition """


def connect(username, password, host, heartbeats=(0, 0)):
    """STOMP connect command.

    username, password:
        These are the needed auth details to connect to the
        message server.

    After sending this we will receive a CONNECTED
    message which will contain our session id.

    """
    if len(heartbeats) != 2:
        raise ValueError('Invalid heartbeat %r' % heartbeats)
    cx, cy = heartbeats
    return (
        'CONNECT\naccept-version:1.1\nhost:%s\nheart-beat:%i,%i\nlogin:%s\npasscode:%s\n\n\x00\n'
         % (host, cx, cy, username, password))


def request_memory_generation_lookup(duration, roq=False):
    """ Function to determine memory required at the data generation step """
    if roq:
        return int(max([8, min([60, duration])]))
    else:
        return 8