def convert_ticker_type(df):
    """
    Convert the column ticker to Text.
    """
    df['Ticker'] = df['Ticker'].astype(str)
    return df


def _PerModeSmall48(x):
    """Takes Numeric Code and returns String API code

    Input Values: 1:"Totals", 2:"PerGame", 3:"Per48"

    Used in:

    """
    measure = {(1): 'Totals', (2): 'PerGame', (3): 'Per48'}
    try:
        return measure[x]
    except:
        raise ValueError('Please enter a number between 1 and ' + str(len(
            measure)))


def isparent(kls):
    """Return True is class is a parent."""
    return kls.__base__ is object


def precision(y_true, y_pred):
    """Precision metric.

    Computes the precision, a metric for multi-label classification of
    how many selected items are relevant. Only computes a batch-wise average of
    precision.
    """
    import keras.backend as k
    true_positives = k.sum(k.round(k.clip(y_true * y_pred, 0, 1)))
    predicted_positives = k.sum(k.round(k.clip(y_pred, 0, 1)))
    return true_positives / (predicted_positives + k.epsilon())


def sanitise_name(name):
    """
    Take a name for a language or a feature which has come from somewhere like
    a CLDF dataset and make sure it does not contain any characters which
    will cause trouble for BEAST or postanalysis tools.
    """
    name = name.replace(' ', '_')
    return name


def delete_certificate(CertificateArn=None):
    """
    Deletes an ACM Certificate and its associated private key. If this action succeeds, the certificate no longer appears in the list of ACM Certificates that can be displayed by calling the  ListCertificates action or be retrieved by calling the  GetCertificate action. The certificate will not be available for use by other AWS services.
    See also: AWS API Documentation

    :example: response = client.delete_certificate(
        CertificateArn='string'
    )

    :type CertificateArn: string
    :param CertificateArn: [REQUIRED]
            String that contains the ARN of the ACM Certificate to be deleted. This must be of the form:
            arn:aws:acm:region:123456789012:certificate/12345678-1234-1234-1234-123456789012
            For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces .

    """
    pass


def full_name(arg_details):
    """Create a full path to the complex object parameter of a
    given argument.
    :param dict arg_details: The details of the argument.
    :returns: str
    """
    return '.'.join([arg_details['path'], arg_details['root']])


def decode_all(res):
    """decode all results fetched from redis"""
    return list(map(bytes.decode, res))


def make_figure_tot_curves(extractors, what):
    """
    $ oq plot 'tot_curves?loss_type=structural&kind=rlz-000&absolute=1'
    """
    import matplotlib.pyplot as plt
    fig = plt.figure()
    [ex] = extractors
    tot = ex.get(what)
    app = ex.get(what.replace('tot_', 'app_'))
    ax = fig.add_subplot(1, 1, 1)
    ax.set_xlabel('return periods')
    ax.set_ylabel('PoE')
    ax.loglog(tot.return_period, tot[:, (0)], '-', label='tot_curves')
    ax.loglog(app.return_period, app[:, (0)], '-', label='app_curves')
    ax.grid(True)
    ax.legend()
    return plt


def broadcast_greater(lhs=None, rhs=None, name=None, attr=None, out=None,
    **kwargs):
    """Returns the result of element-wise **greater than** (>) comparison operation with broadcasting.

    Example::

       x = [[ 1.,  1.,  1.],
            [ 1.,  1.,  1.]]

       y = [[ 0.],
            [ 1.]]

       broadcast_greater(x, y) = [[ 1.,  1.,  1.],
                                  [ 0.,  0.,  0.]]

    Defined in src/operator/tensor/elemwise_binary_broadcast_op_logic.cc:L82

    Parameters
    ----------
    lhs : Symbol
        First input to the function
    rhs : Symbol
        Second input to the function

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

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


def api_gateway_name():
    """ the name of the default api gateway """
    return 'api'


def reaction_charge(reaction, compound_charge):
    """Calculate the overall charge for the specified reaction.

    Args:
        reaction: :class:`psamm.reaction.Reaction`.
        compound_charge: a map from each compound to charge values.
    """
    charge_sum = 0.0
    for compound, value in reaction.compounds:
        charge = compound_charge.get(compound.name, float('nan'))
        charge_sum += charge * float(value)
    return charge_sum


def lonely_equal_constructor(loader, node):
    """Solve/monkey-patch a very old bug.
    https://bitbucket.org/xi/pyyaml/issues/49/plain-equal-sign-as-node-content-results
    """
    s = loader.construct_scalar(node)
    return s


@staticmethod
def get_ps1():
    """
        Returns the PS1, the basic shell prompt
        """
    return '$ '


@classmethod
def from_dict(cls, parsed_dict):
    """Create an Event from a dictionary.

        Args:
            parsed_dict (dict): The dictionary representation of the event.

        """
    return cls(parsed_dict)


def update(*args, **kwds):
    """od.update(E, **F) -> None.  Update od from dict/iterable E and F.

        If E is a dict instance, does:           for k in E: od[k] = E[k]
        If E has a .keys() method, does:         for k in E.keys(): od[k] = E[k]
        Or if E is an iterable of items, does:   for k, v in E: od[k] = v
        In either case, this is followed by:     for k, v in F.items(): od[k] = v

        """
    if len(args) > 2:
        raise TypeError(
            'update() takes at most 2 positional arguments (%d given)' % (
            len(args),))
    elif not args:
        raise TypeError('update() takes at least 1 argument (0 given)')
    self = args[0]
    other = ()
    if len(args) == 2:
        other = args[1]
    if isinstance(other, dict):
        for key in other:
            self[key] = other[key]
    elif hasattr(other, 'keys'):
        for key in other.keys():
            self[key] = other[key]
    else:
        for key, value in other:
            self[key] = value
    for key, value in kwds.items():
        self[key] = value


def _convert_colormap(given_colormap):
    """Convert the given colormap into one that can be used by Matplotlib.

    References:
        - https://matplotlib.org/api/pyplot_summary.html#colors-in-matplotlib
        - https://matplotlib.org/api/cm_api.html
        - https://matplotlib.org/tutorials/index.html#tutorials-colors
        - https://matplotlib.org/tutorials/colors/colormaps.html#sphx-glr-tutorials-colors-colormaps-py
    """
    return given_colormap


def _sabr_implied_vol_hagan_A4(underlying, strike, maturity, alpha, beta,
    rho, nu):
    """_sabr_implied_vol_hagan_A4
    One of factor in hagan formua.
    See :py:func:`sabr_implied_vol_hagan`.

    A_{4}(K, S; T)
        & := &
            1
            +
            \\left(
                \\frac{(1 - \\beta)^{2}}{24}
                    \\frac{lpha^{2}}{(SK)^{1-\\beta}}
                + \\frac{1}{4}
                    \\frac{\\rho\\beta
ulpha}{(SK)^{(1-\\beta)/2}}
                + \\frac{2 - 3\\rho^{2}}{24}
u^{2}
            \\right) T

    :param float underlying:
    :param float strike:
    :param float maturity:
    :param float alpha:
    :param float beta:
    :param float rho:
    :param float nu:

    :return: value of factor.
    :rtype: float.
    """
    one_minus_beta = 1.0 - beta
    one_minus_beta_half = one_minus_beta / 2.0
    one_minus_beta2 = one_minus_beta ** 2
    numerator1 = one_minus_beta2 * alpha * alpha
    denominator1 = 24.0 * (underlying * strike) ** one_minus_beta
    term1 = numerator1 / denominator1
    numerator2 = rho * beta * nu * alpha
    denominator2 = 4.0 * (underlying * strike) ** one_minus_beta_half
    term2 = numerator2 / denominator2
    term3 = (2.0 - 3.0 * rho * rho) * nu * nu / 24.0
    return 1.0 + (term1 + term2 + term3) * maturity


def is_child_node(child, parent):
    """Returns True if child is an eventual child node of parent"""
    node = child
    while node is not None:
        if node == parent:
            return True
        node = node.parent
    return False


def longest_increasing_subsequence(_list):
    """
    The Longest Increasing Subsequence (LIS) problem is to find the length of the longest subsequence of a
    given sequence such that all elements of the subsequence are sorted in increasing order. For example,
    the length of LIS for [10, 22, 9, 33, 21, 50, 41, 60, 80] is 6 and LIS is [10, 22, 33, 50, 60, 80].

    :param _list: an array of elements
    :return: returns a tuple of maximum length of lis and an array of the elements of lis
    """
    lis = [1] * len(_list)
    elements = [0] * len(_list)
    for i in range(1, len(_list)):
        for j in range(0, i):
            if _list[i] > _list[j] and lis[i] < lis[j] + 1:
                lis[i] = lis[j] + 1
                elements[i] = j
    maximum = max(lis)
    idx = lis.index(maximum)
    seq = [_list[idx]]
    while idx != elements[idx]:
        idx = elements[idx]
        seq.append(_list[idx])
    return maximum, seq[::-1]


def load_handlers(name):
    """Load the (URL pattern, handler) tuples for each component."""
    mod = __import__(name, fromlist=['default_handlers'])
    return mod.default_handlers


def changePassword(user, oldpswd, newpswd):
    """
    This function allows to change the user password on the KDC.

    @param user:          a string containing the Kerberos user name. A realm may be
        included by appending an '@' followed by the realm string to the actual user id.
        If no realm is supplied, then the realm set in the default_realm argument will
        be used.
    @param oldpswd:       a string containing the old (current) password for the user.
    @param newpswd:       a string containging the new password for the user.
    @return:              True if password changing succeeds, False otherwise.
    """
    raise NotImplementedError


@staticmethod
def _get_operator_class_name(task_detail_type):
    """ Internal helper gets the name of the Airflow operator class. We maintain
      this in a map, so this method really returns the enum name, concatenated
      with the string "Operator".
    """
    task_type_to_operator_prefix_mapping = {'pydatalab.bq.execute': (
        'Execute',
        'google.datalab.contrib.bigquery.operators._bq_execute_operator'),
        'pydatalab.bq.extract': ('Extract',
        'google.datalab.contrib.bigquery.operators._bq_extract_operator'),
        'pydatalab.bq.load': ('Load',
        'google.datalab.contrib.bigquery.operators._bq_load_operator'),
        'Bash': ('Bash', 'airflow.operators.bash_operator')}
    operator_class_prefix, module = task_type_to_operator_prefix_mapping.get(
        task_detail_type, (None, __name__))
    format_string = '{0}Operator'
    operator_class_name = format_string.format(operator_class_prefix)
    if operator_class_prefix is None:
        return format_string.format(task_detail_type), module
    return operator_class_name, module


def do_OP_SUBSTR(vm):
    """
    >>> s = [b'abcdef', b'', b'']
    >>> do_OP_SUBSTR(s, require_minimal=True)
    >>> print(s)
    [b'de']
    """
    pos = vm.pop_nonnegative()
    length = vm.pop_nonnegative()
    vm.append(vm.pop()[length:length + pos])


@staticmethod
def _split_message(msg: tuple) ->tuple:
    """Return request_id, data, max_doc_size.

        :Parameters:
          - `message`: (request_id, data, max_doc_size) or (request_id, data)
        """
    if len(msg) == 3:
        return msg
    else:
        request_id, data = msg
        return request_id, data, 0


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

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


@staticmethod
def beta_r(r, r_ani):
    """
        anisotropy as a function of radius

        :param r: 3d radius
        :param r_ani: anisotropy radius
        :return: beta
        """
    return r ** 2 / (r_ani ** 2 + r ** 2)


def __dict_replace(s, d):
    """Replace substrings of a string using a dictionary."""
    for key, value in d.items():
        s = s.replace(key, value)
    return s


def stri(val):
    """Retourne la chaine representant la valeur entiere"""
    return '{0:d}'.format(val)


@classmethod
def address_to_hashX(cls, address):
    """Return a hashX given a coin address."""
    return cls.hashX_from_script(cls.pay_to_address_script(address))


def keep_phase_in_dataset(saved_game_proto):
    """ Filter function that decides if we should put a phase in the dataset
        :param saved_game_proto: A `.proto.game.SavedGame` object from the dataset.
        :return: A boolean that indicates if we should keep this phase or not.
    """
    if saved_game_proto.map.startswith('standard'):
        return True
    return False


def _remove_empty_entries(entries):
    """Remove empty entries in a list"""
    valid_entries = []
    for entry in set(entries):
        if entry:
            valid_entries.append(entry)
    return sorted(valid_entries)


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 to_fahrenheit(c):
    """Convert Centigrade to Fahrenheits."""
    return c * 9 / 5 + 32


def _read_rest_frequency(header):
    """Read the rest frequency in [Hz]."""
    try:
        nu = header['restfreq']
    except KeyError:
        try:
            nu = header['restfrq']
        except KeyError:
            nu = header['crval3']
    return nu


def to_unit_box(x, lb, ub):
    """Maps a set of points to the unit box

    :param x: Points to be mapped to the unit box, of size npts x dim
    :type x: numpy.array
    :param lb: Lower bounds, of size 1 x dim
    :type lb: numpy.array
    :param ub: Upper bounds, of size 1 x dim
    :type ub: numpy.array
    :return: Points mapped to the unit box
    :rtype: numpy.array
    """
    return (x - lb) / (ub - lb)


def clean_line(time, project, log):
    """Cleans line data from unnecessary chars"""
    time = time[:-1]
    if project and project[-1] == '\n':
        project = project[:-1]
    if log and log[-1] == '\n':
        log = log[:-1]
    return time, project, log


@classmethod
def get_elasticsearch_schema(clz, _es_version):
    """
        Returns the elasticsearch schema for the _invenio_explicit_acls property.

        The property looks like::

            _invenio_explicit_acls [{
               "timestamp": "...when the ACL has been applied to the resource",
               "acl": <id of the acl>,
               "operation": name of the operation
               "role": [1,2]
            }]

        """
    return {'type': 'integer'}


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

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

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


@classmethod
def register_tool(cls, tool_name: str, reset_function):
    """
        Identifies that the given Tool should be made available.
        Args:
            tool_name: A unique string identifying this tool.
            reset_function: The function to call to reset the Tool.

        Returns:

        """
    if tool_name in cls.TOOLS:
        raise Exception('Tool namespace {} already registered.')
    cls.TOOLS[tool_name] = {'reset': reset_function}


def OptionName(widget):
    """Returns the qualified path name for the widget. Normally used to set
    default options for subwidgets. See tixwidgets.py"""
    return widget.tk.call('tixOptionName', widget._w)


def indent(string):
    """Return an indented string."""
    indent_char_count = 4
    return ' ' * indent_char_count + str(string)


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 render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

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


def insert(text: str=''):
    """Insert text at cursor position

    :param text: Text, Text to insert at the cursor position
    :type text: str
    """
    pass


@classmethod
def from_dict(cls, connection, data, casout=None, **kwargs):
    """
        Create a CASTable from a dictionary

        Parameters
        ----------
        connection : :class:`CAS`
            The :class:`CAS` connection to read the data into.
        data : dict
            The dictionary containing the data.
        casout : string or :class:`CASTable`, optional
            The output table specification.  This includes the following parameters.
                name : string, optional
                    Name of the output CAS table.
                caslib : string, optional
                    CASLib for the output CAS table.
                label : string, optional
                    The label to apply to the output CAS table.
                promote : boolean, optional
                    If True, the output CAS table will be visible in all sessions.
                replace : boolean, optional
                    If True, the output CAS table will replace any existing CAS.
                    table with the same name.
        **kwargs : keyword arguments
            Keyword arguments sent to :meth:`pandas.DataFrame.from_dict`.

        See Also
        --------
        :meth:`pandas.DataFrame.from_dict`

        Returns
        -------
        :class:`CASTable`

        """
    return cls._from_any('dict', connection, data, casout=casout, **kwargs)


def unit_to_factor_in_microns(unit: str) ->float:
    """
        Convert a string naming the unit of measure to its value in microns
        :param unit:
        :return:
        """
    if unit == 'microns':
        return 1.0
    if unit == 'millimeters':
        return 1000.0
    if unit == 'centimeters:':
        return 10000.0
    if unit == 'meters':
        return 1000000.0


@classmethod
def from_DataFrame(cls, df, name, description, refgen, rawtype=None,
    zscore_cutoff=3, **kwargs):
    """
            The method will read the table in (as a pandas dataframe),
            build the Expr object passing all keyword arguments in ``**``kwargs
            to the classmethod Expr.from_DataFrame(...). See additional
            ``**``kwargs in COB.from_Expr(...)

            Parameters
            ----------
            df : pandas.DataFrame
                A Pandas dataframe containing the expression information.
                Assumes gene names are in the index while accessions
                (experiments) are stored in the columns.
            name : str
                Name of the dataset stored in camoco database
            description : str
                Short string describing the dataset
            refgen : camoco.RefGen
                A Camoco refgen object which describes the reference
                genome referred to by the genes in the dataset. This
                is cross references during import so we can pull information
                about genes we are interested in during analysis.
            rawtype : str (default: None)
                This is noted here to reinforce the impotance of the rawtype
                passed to camoco.Expr.from_DataFrame. See docs there
                for more information.
            zscore_cutoff : int (defualt: 3)
                The zscore cutoff for the network.
            \\*\\*kwargs : key,value pairs
                additional parameters passed to subsequent methods.
                (see Expr.from_DataFrame)

        """
    expr = super().from_DataFrame(df, name, description, refgen, rawtype,
        zscore_cutoff=zscore_cutoff, **kwargs)
    return cls.from_Expr(expr)


def union(*sets):
    """
    Return the union between all arguments.
    """
    first, *others = sets
    out = set(first)
    for other in others:
        out.update(other)
    return out


@classmethod
def getArgumentsFromRequest(klass, session, request):
    """Extract needed arguments for the constructor from the request.

        :param session: the SQLAlchemy session
        :param request: the Pyramid request instance
        :rtype: a sequence of arguments
        """
    return [getattr(request, '_LOCALE_', 'en')]


def find_root_and_group(ds):
    """Find the root and group name of a netCDF4/h5netcdf dataset."""
    hierarchy = ()
    while ds.parent is not None:
        hierarchy = (ds.name.split('/')[-1],) + hierarchy
        ds = ds.parent
    group = '/' + '/'.join(hierarchy)
    return ds, group


def isnumeric(value):
    """Does a string value represent a number (positive or negative?)

    Args:
        value (str): A string

    Returns:
        bool: True or False
    """
    try:
        float(value)
        return True
    except:
        return False


def round_channels(channels, divisor=8):
    """
    Round weighted channel number (make divisible operation).

    Parameters:
    ----------
    channels : int or float
        Original number of channels.
    divisor : int, default 8
        Alignment value.

    Returns
    -------
    int
        Weighted number of channels.
    """
    rounded_channels = max(int(channels + divisor / 2.0) // divisor *
        divisor, divisor)
    if float(rounded_channels) < 0.9 * channels:
        rounded_channels += divisor
    return rounded_channels


def argv_to_dict(argv):
    """Turns parameters in the form of '--key value' into a dict {'key': 'value'}
    """
    cli_dict = {}
    for i in range(len(argv)):
        if argv[i][0] == '-':
            key = argv[i].strip('-')
            value = argv[i + 1] if len(argv) > i + 1 else None
            if not value or value[0] == '-':
                cli_dict[key] = True
            else:
                cli_dict[key] = value
    return cli_dict


def float_if_not_none(value):
    """
    Returns an float(value) if the value is not None.

    :param value: None or a value that can be converted to an float.
    :return: None or float(value)
    """
    return None if value is None else float(value)


@classmethod
def zone_operation_mode(cls, mode: str):
    """
        Payload to set operation mode for *zone*
        """
    return {'mode': mode}


def display_bloch_sphere(**kwargs):
    """
    Prints an error message.
    """
    print('display_bloch_sphere not available on this version.')


def _nonpolarized_magnetic(R):
    """Convert magnetic reflectivity to unpolarized representation.

    Unpolarized magnetic data adds the cross-sections of the magnetic
    data incoherently and divides by two.
    """
    return sum(R) / 2


@staticmethod
def create(cmd_args):
    """
        Create ScenarioManager Instance(YamlScenarioManager or JsonScenarioManager)
        Args:
            cmd_args: Command Line Arguments
        Returns:
            scenario manager instance
        """
    scenario_file_format = cmd_args.format
    scenario_manager_cls = scenario_file_format.capitalize(
        ) + 'ScenarioManager'
    instance = globals()[scenario_manager_cls]
    return instance(cmd_args)


@classmethod
def prettyqty(cls, amount):
    """return a quantity as kilos (k) or megas (M) if  justified)"""
    if amount < 10000:
        return '%d' % (amount,)
    if amount < 10000000.0:
        return '%dk' % (amount // 1000,)
    if amount < 100000000.0:
        return '%1.1fM' % (amount // 10000000.0,)
    return '%dM' % (amount // 10000000.0,)


def _remove_end_characters(line):
    """Removes line ending characters"""
    if line[-2:] == '\r\n':
        return line[:-2], True
    elif line[-1:] in '\r\n':
        return line[:-1], True
    return line, False


def driver_variables_paste(replace: bool=False):
    """Add copied driver variables to the active driver

    :param replace: Replace Existing, Replace existing driver variables, instead of just appending to the end of the existing list
    :type replace: bool
    """
    pass


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


def diff_align(dfs, groupers):
    """ Align groupers to newly-diffed dataframes

    For groupby aggregations we keep historical values of the grouper along
    with historical values of the dataframes.  The dataframes are kept in
    historical sync with the ``diff_loc`` and ``diff_iloc`` functions above.
    This function copies that functionality over to the secondary list of
    groupers.
    """
    old = []
    while len(dfs) < len(groupers):
        old.append(groupers.popleft())
    if dfs:
        n = len(groupers[0]) - len(dfs[0])
        if n:
            old.append(groupers[0][:n])
            groupers[0] = groupers[0][n:]
    assert len(dfs) == len(groupers)
    for df, g in zip(dfs, groupers):
        assert len(df) == len(g)
    return old, groupers


def binomial(n, k, factorial):
    """Returns C(n,k) = n!/(k!(n-k)!)."""
    assert n >= 0 and k >= 0 and n >= k, 'n and k should be non-negative integers with n >= k.'
    c = factorial[int(n)] / (factorial[int(k)] * factorial[int(n - k)])
    return c


def export_discourse_transcription(discourse, path, trans_delim='.',
    single_line=False):
    """
    Export an transcribed discourse to a text file

    Parameters
    ----------
    discourse : Discourse
        Discourse object to export
    path : str
        Path to export to
    trans_delim : str, optional
        Delimiter for segments, defaults to ``.``
    single_line : bool, optional
        Flag to enforce all text to be on a single line, defaults to False.
        If False, lines are 10 words long.
    """
    with open(path, encoding='utf-8', mode='w') as f:
        count = 0
        for i, wt in enumerate(discourse):
            count += 1
            f.write(trans_delim.join(wt.transcription))
            if i != len(discourse) - 1:
                if not single_line and count <= 10:
                    f.write(' ')
                else:
                    count = 0
                    f.write('\n')


@classmethod
def read(cls, *args, **kwargs):
    """NIKA2 IDL Pipeline Map reader

        Parameters
        ----------
        filename : str
            the fits filename
        revert : boolean
             use if to return -1 * data
        """
    return cls(*args, **kwargs)


def convertToDashes(commands):
    """
    Converts Cyther's pass off notation to the regular dash notation (_a becomes -a)
    Args:
        commands (list|tuple): The unprocessed commands
    Returns (list): The processed commands
    """
    processed = []
    for command in commands:
        if command[0] == '_':
            if command[1] == '_':
                command = '--' + command[2:]
            else:
                command = '-' + command[1:]
        processed.append(command)
    return processed


@classmethod
def format_real(cls, num):
    """Format a float in natural mode"""
    return '%g' % num


@classmethod
def install_parser(cls, parser_type, *tags):
    """Installs an URDF parser type for a defined tag.

        Parameters
        ----------
        parser_type : type
            Python class handling URDF parsing of the tag.
        tags : str
            One or more URDF string tag that the parser can parse.
        """
    if len(tags) == 0:
        raise ValueError('Must define at least one tag')
    for tag in tags:
        cls._parsers[tag] = parser_type


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 template_renderer(f):
    """Set a custom template renderer."""
    global _render_string
    _render_string = f
    return f


def smart_urljoin(base, url):
    """urljoin, only an empty fragment from the relative(?) URL will be
    preserved.
    """
    from .compat.moves.urllib.parse import urljoin
    joined = urljoin(base, url)
    if url.endswith('#') and not joined.endswith('#'):
        joined += '#'
    return joined


def printReport(parsedData, formatting):
    """
    Prints the minimum, maximum and average of every measurement in the data
    Arguments:
        parsedData: The
        formatting: The output format of the report. "pretty" or "csv"
    """
    if formatting == 'pretty':
        colwidths = [50, 17, 17, 17]
        separator = '\t'
    elif formatting == 'csv':
        colwidths = [0, 0, 0, 0]
        separator = ','
    print('measurement'.ljust(colwidths[0]) + separator + 'min'.ljust(
        colwidths[1]) + separator + 'average'.ljust(colwidths[2]) +
        separator + 'max'.ljust(colwidths[3]))
    if formatting == 'pretty':
        print('-' * 120)
    for resource, data in parsedData.items():
        datalength = len(data)
        for i in range(1, datalength):
            biggest = -1e+40
            smallest = 1e+40
            average = 0
            for n in data[i]:
                if n > biggest:
                    biggest = n
                if n < smallest:
                    smallest = n
                average += n
            average /= len(data[i])
            if data[0][i - 1] != 'value':
                line = resource + '-' + data[0][i - 1]
            else:
                line = resource
            print(line.ljust(colwidths[0]) + separator + str(smallest).
                ljust(colwidths[1]) + separator + str(average).ljust(
                colwidths[2]) + separator + str(biggest).ljust(colwidths[3]))


def generateFinishedBuilds(builders=None, branches=None, num_builds=None,
    finished_before=None, max_search=200):
    """Return a generator that will produce IBuildStatus objects each
        time you invoke its .next() method, starting with the most recent
        finished build and working backwards.

        @param builders: this is a list of Builder names, and the generator
                         will only produce builds that ran on the given
                         Builders. If the list is empty, produce builds from
                         all Builders.

        @param branches: this is a list of branch names, and the generator
                         will only produce builds that used the given
                         branches. If the list is empty, produce builds from
                         all branches.

        @param num_builds: the generator will stop after providing this many
                           builds. The default of None means to produce as
                           many builds as possible.

        @type finished_before: int: a timestamp, seconds since the epoch
        @param finished_before: if provided, do not produce any builds that
                                finished after the given timestamp.

        @type max_search: int
        @param max_search: this method may have to examine a lot of builds
                           to find some that match the search parameters,
                           especially if there aren't any matching builds.
                           This argument imposes a hard limit on the number
                           of builds that will be examined within any given
                           Builder.
        """


def negative(data=None, name=None, attr=None, out=None, **kwargs):
    """Numerical negative of the argument, element-wise.

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

       - negative(default) = default
       - negative(row_sparse) = row_sparse
       - negative(csr) = csr

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

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

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


def create_source_map(source, on, source_keys, comparison_func):
    """
    Splits a source into groups using a comparison function.

    :param pandas.DataFrame source: Source list.
    :param str on: `source[on]` is used as an operand in `comparison_func`.
    :param list source_keys: Secondary operand in `comparison_func`.
    :param function comparison_func: Function to compare `source[on]` to
        `source_keys`. Must return a boolean mask the same length as `source`.
    :return: Map of source_keys to subsets of the source that satisfy the
        `comparison_func`
    :rtype: dict
    """
    source_map = {}
    for key in source_keys:
        select = comparison_func(source[on], key)
        source_map[key] = source[select]
    return source_map


def list_a_minus_list_b(list_a, list_b):
    """This method assumes input is two lists with unique elements aka sets.

    It then returns all unique elements in list_a, not present in list_b.

    :param list_a:
    :param list_b:
    :return: list of elements only in list_a OR an empty list
    """
    return list(set(list_a) - set(list_b))


def cancel_cluster(ClusterId=None):
    """
    Cancels a cluster job. You can only cancel a cluster job while it's in the AwaitingQuorum status. You'll have at least an hour after creating a cluster job to cancel it.
    See also: AWS API Documentation

    Examples
    This operation cancels a cluster job. You can only cancel a cluster job while it's in the AwaitingQuorum status.
    Expected Output:

    :example: response = client.cancel_cluster(
        ClusterId='string'
    )

    :type ClusterId: string
    :param ClusterId: [REQUIRED]
            The 39-character ID for the cluster that you want to cancel, for example CID123e4567-e89b-12d3-a456-426655440000 .

    :rtype: dict
    :return: {}

    """
    pass


def maybe_unroll_group(g):
    """Unroll group with only one member."""
    try:
        size = len(g.tasks)
    except TypeError:
        try:
            size = g.tasks.__length_hint__()
        except (AttributeError, TypeError):
            pass
        else:
            return list(g.tasks)[0] if size == 1 else g
    else:
        return g.tasks[0] if size == 1 else g


@staticmethod
def id_function(mimetype):
    """The function used to return the codename."""
    if mimetype in ('image/png', 'image/svg'):
        return 'chart'


def make_first_upper(s):
    """Uppercase the first letter of s, leaving the rest alone."""
    return s[:1].upper() + s[1:]


def Index(func):
    """Decorator to mark function as index.

    Marks instance methods of a DBObject-decorated class as being used for
    indexing. The function name is used as the index name, and the return
    value is used as the index value.

    Note that callables are call recursively so in theory you can return
    a function which will be called to get the index value.
    """
    func.is_index = True
    return func


def _construct_result(left, result, index, name, dtype):
    """
    If the raw op result has a non-None name (e.g. it is an Index object) and
    the name argument is None, then passing name to the constructor will
    not be enough; we still need to override the name attribute.
    """
    out = left._constructor(result, index=index, dtype=dtype)
    out.name = name
    return out


def int_or_none(val):
    """Attempt to parse an integer value, or None."""
    if val is None:
        return val
    else:
        return int(val)


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

        :param FileRequestCloseDetails val:
        :rtype: EventDetails
        """
    return cls('file_request_close_details', val)


@classmethod
def range(cls, from_=1, to=None, step=1):
    """
        Returns an iterator over specified comics.

        Use negative numbers to specify from the end.

        :param int from_: The comic to start from. Defaults to the first.
        :param Optional[int] to: The comic to end by (exclusive). Defaults to last + 1.
        :param int step: The step amount. Defaults to one.
        :return: A range over the requested comics.
        """
    if to is None:
        if step < 0:
            to = 0
        else:
            to = cls.latest() + 1
    return range(from_, to, step)


def _get_temporal_coordinates(timestamps):
    """ Returns temporal coordinates dictionary for creating xarray DataArray/Dataset

    :param timestamps: timestamps
    :type timestamps: EOpatch.timestamp
    :return: temporal coordinates
    :rtype: dict {'time': }
    """
    return {'time': timestamps}


def duplicate(image):
    """Copy a channel. Alias for :py:meth:`PIL.Image.Image.copy`.

    :rtype: :py:class:`~PIL.Image.Image`
    """
    return image.copy()


def minimal_grid(x, y, tol=1e-06, rel=False):
    """Greedy algorithm for building a reduced-order spline

    This function is a slight generalization of the core function
    from `romspline` -- namely, `romspline.greedy._greedy` --
    tailored to the needs of this package.  This function should
    behave nearly the same as the `romspline` function (except that
    this function returns fewer quantities), but also accepts a
    callable object as the `tol` parameter, to enable more general
    evaluations of the error.

    Parameters
    ==========
    x: array of float
        An ordered series of sampling points.
    y: array of float
        Function values sampled at points given by `x`.
    tol: float or callable [defaults to 1e-6]
        If given a float, this function will iteratively increase the
        number of sampling points until the spline formed from those
        points is within this value of the input data at each input
        sample.  If given a callable object, that object must be as
        described in the Notes section below.
    rel: bool [defaults to False]
        If `tol` is a float and this is true, the tolerance will be
        taken relative to the maximum absolute value in the input `y`
        data.  Note that if `tol` is callable this parameter is
        ignored.

    Returns
    =======
    include_sample: array of bool
        Boolean array of the same length as `x` determining whether
        or not the corresponding point should be included in a
        reduced-order spline.  Note that numpy arrays can be indexed
        with this array, so that `x[include_sample]` will give the
        set of knots and `y[include_sample]` will give the
        corresponding set of data values with which to build the
        reduced-order spline.

    Notes
    =====
    The `tol` callable, if given, is used to decide whether or not
    the current trial spline is acceptable, and if not which sample
    point to include for the next trial spline.  It must be callable
    with the signature (x, y, y_greedy), and is expected to return
    either None (if the trial is acceptable) or the index of the next
    sample point to include.  Here, `x` and `y` are just the
    corresponding inputs to this function, and `y_greedy` is a set of
    data points representing the values of the trial reduced-order
    spline evaluated on `x`.  For example, the following function
    would behave equivalently to the default parameters:

        def tol(x, y, y_greedy):
            errors = np.abs(y-y_greedy)
            i_next = np.argmax(errors)
            if errors[i_next] < 1e-6:
                return None
            return i_next

    """
    import numpy as np
    from scipy.interpolate import CubicSpline as spline
    deg = 3
    if callable(tol):
        next_sample = tol
    else:
        if rel:
            ymax = np.max(np.abs(y))
            if ymax == 0.0:
                raise ValueError('All input `y` data samples are zero.')
            tol *= ymax

        def next_sample(x, y, y_greedy):
            errors = np.abs(y - y_greedy)
            i_next = np.argmax(errors)
            if errors[i_next] < tol:
                return None
            return i_next
    include_sample = np.zeros(len(x), dtype=bool)
    include_sample[np.linspace(0, len(x) - 1, num=deg + 1, dtype=int)] = True
    for _ in range(len(x)):
        s = spline(x[include_sample], y[include_sample])
        i_next = next_sample(x, y, s(x))
        if i_next is None:
            break
        include_sample[i_next] = True
    return include_sample


def name_for_collection_relationship(base, local_cls, referred_cls, constraint
    ):
    """Return the attribute name that should be used to refer from one
    class to another, for a collection reference.

    The default implementation is::

        return referred_cls.__name__.lower() + "_collection"

    Alternate implementations
    can be specified using the
    :paramref:`.AutomapBase.prepare.name_for_collection_relationship`
    parameter.

    :param base: the :class:`.AutomapBase` class doing the prepare.

    :param local_cls: the class to be mapped on the local side.

    :param referred_cls: the class to be mapped on the referring side.

    :param constraint: the :class:`_schema.ForeignKeyConstraint` that is being
     inspected to produce this relationship.

    """
    return referred_cls.__name__.lower() + '_collection'


@staticmethod
def _whois_filter(sources, src, whoismodule, whoismodule_cache):
    """
        Help method for filtering sources by abuse group's networks
        """
    if src not in whoismodule_cache:
        whoismodule_cache[src] = bool(whoismodule.lookup(src))
    if whoismodule_cache[src]:
        sources.add(src)
    return sources


@classmethod
def from_dict(cls, body):
    """Convert a dictionary to an Employee."""
    return cls(**body)


def stringified_dict_contains_value(key, value, str_dict):
    """Checks if dict in for of string like "{'test': 5}" contains
    key/value pair. This works faster, then creating actual dict
    from string since this operation is called for each task in case
    of kwargs search."""
    value = str(value)
    try:
        key_index = str_dict.index(key) + len(key) + 3
    except ValueError:
        return False
    try:
        comma_index = str_dict.index(',', key_index)
    except ValueError:
        comma_index = str_dict.index('}', key_index)
    return str(value) == str_dict[key_index:comma_index].strip('"\'')


def coupon_close(message=''):
    """ It needs to be possible to open new coupons after this is called.
        You must call coupon_totalize before calling this method.

        @param message:   promotional message
        @type message:    str

        @rtype:           int
        @returns:         identifier of the coupon.
        """


@staticmethod
def remove_underscore_and_capitalize_word(words):
    """
        Remove underscore and capitalize the first letter of word
        :param words:
        :return:
        """
    words_without_underscore = str(words).replace('_', ' ')
    return words_without_underscore.title()


def includeme(config):
    """ Pyramid includeme hook.

    :param config: app config
    :type config: :class:`pyramid.config.Configurator`
    """
    config.scan(__name__)


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 left_pad(text: str, length: int, padding: str) ->str:
    """
    Pad text from the left to a certain length

    :param text: The text to pad
    :param length: The length to pad to
    :param padding: The padding to use
    :raises ValueError: If the padding is invalid or the text is too long
    :return: The padded text
    """
    if len(padding) != 1:
        raise ValueError("Only single-character padding supported: '{}'".
            format(padding))
    if len(text) > length:
        raise ValueError("Text more than {} characters long: '{}'".format(
            length, text))
    number_of_pads = length - len(text)
    return number_of_pads * padding + text


@staticmethod
def _sort_and_trim(data, reverse=False):
    """Sorts a dictionary with at least two fields on each of them sorting
        by the second element.

        .. warning::
          Right now is hardcoded to 10 elements, improve the command line
          interface to allow to send parameters to each command or globally.
        """
    threshold = 10
    data_list = data.items()
    data_list = sorted(data_list, key=lambda data_info: data_info[1],
        reverse=reverse)
    return data_list[:threshold]


def sc_mulsub(aa, bb, cc):
    """
    (cc - aa * bb) % l
    """
    return cc - aa * bb


def path2ScriptId(path):
    """Answers the scriptId, derived from the __file__ of the main source."""
    return path.split('/src/')[-1]


@classmethod
def get_arthur_params_from_url(cls, url):
    """ Get the arthur params given a URL for the data source """
    tokens = url.split(' ', 1)
    return {'url': tokens[0]}


def create_instances_from_snapshot(instanceNames=None, availabilityZone=
    None, instanceSnapshotName=None, bundleId=None, userData=None,
    keyPairName=None):
    """
    Uses a specific snapshot as a blueprint for creating one or more new instances that are based on that identical configuration.
    See also: AWS API Documentation

    :example: response = client.create_instances_from_snapshot(
        instanceNames=[
            'string',
        ],
        availabilityZone='string',
        instanceSnapshotName='string',
        bundleId='string',
        userData='string',
        keyPairName='string'
    )

    :type instanceNames: list
    :param instanceNames: [REQUIRED]
            The names for your new instances.
            (string) --

    :type availabilityZone: string
    :param availabilityZone: [REQUIRED]
            The Availability Zone where you want to create your instances. Use the following formatting: us-east-1a (case sensitive). You can get a list of availability zones by using the get regions operation. Be sure to add the include availability zones parameter to your request.

    :type instanceSnapshotName: string
    :param instanceSnapshotName: [REQUIRED]
            The name of the instance snapshot on which you are basing your new instances. Use the get instance snapshots operation to return information about your existing snapshots.

    :type bundleId: string
    :param bundleId: [REQUIRED]
            The bundle of specification information for your virtual private server (or instance ), including the pricing plan (e.g., micro_1_0 ).

    :type userData: string
    :param userData: You can create a launch script that configures a server with additional user data. For example, apt-get  y update .
            Note
            Depending on the machine image you choose, the command to get software on your instance varies. Amazon Linux and CentOS use yum , Debian and Ubuntu use apt-get , and FreeBSD uses pkg . For a complete list, see the Dev Guide .

    :type keyPairName: string
    :param keyPairName: The name for your key pair.

    :rtype: dict
    :return: {
        'operations': [
            {
                'id': 'string',
                'resourceName': 'string',
                'resourceType': 'Instance'|'StaticIp'|'KeyPair'|'InstanceSnapshot'|'Domain'|'PeeredVpc',
                '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'
                },
                'isTerminal': True|False,
                'operationDetails': 'string',
                'operationType': 'DeleteInstance'|'CreateInstance'|'StopInstance'|'StartInstance'|'RebootInstance'|'OpenInstancePublicPorts'|'PutInstancePublicPorts'|'CloseInstancePublicPorts'|'AllocateStaticIp'|'ReleaseStaticIp'|'AttachStaticIp'|'DetachStaticIp'|'UpdateDomainEntry'|'DeleteDomainEntry'|'CreateDomain'|'DeleteDomain'|'CreateInstanceSnapshot'|'DeleteInstanceSnapshot'|'CreateInstancesFromSnapshot',
                'status': 'NotStarted'|'Started'|'Failed'|'Completed',
                'statusChangedAt': datetime(2015, 1, 1),
                'errorCode': 'string',
                'errorDetails': 'string'
            },
        ]
    }

    """
    pass


@staticmethod
def can_diff(msg_a, msg_b):
    """
        Check if two thrift messages are diff ready.

        Returns a tuple of (boolean, reason_string), i.e. (False, reason_string)
        if the messages can not be diffed along with the reason and
        (True, None) for the opposite case
        """
    if msg_a.method != msg_b.method:
        return False, 'method name of messages do not match'
    if len(msg_a.args) != len(msg_b.args) or not msg_a.args.is_isomorphic_to(
        msg_b.args):
        return False, 'argument signature of methods do not match'
    return True, None


def __set_current_image(ax, img):
    """Helper to set the current image in pyplot mode.

    If the provided `ax` is not `None`, then we assume that the user is using the object API.
    In this case, the pyplot current image is not set.
    """
    if ax is None:
        import matplotlib.pyplot as plt
        plt.sci(img)


def _run_wsgi_app(*args):
    """This function replaces itself to ensure that the test module is not
    imported unless required.  DO NOT USE!
    """
    global _run_wsgi_app
    from ..test import run_wsgi_app as _run_wsgi_app
    return _run_wsgi_app(*args)


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


def get_occurrences():
    """Return the list of occurrences of where and when the agenda
        item will happen.
        """


def serialize_ntriples(graph, f):
    """Serialize some graph to f as ntriples."""
    for triple in graph:
        f.write(str(triple))


def remove_extra_digits(x, prog):
    """
    Remove extra digits
    x is a string,
    prog is always the following '_sre.SRE_Pattern':
    prog = re.compile("\\d*[.]\\d*([0]{5,100}|[9]{5,100})\\d*\\Z").
    However, it is compiled outside of this sub-function
    for performance reasons.
    """
    if not isinstance(x, str):
        return x
    result = prog.match(x)
    if result:
        decimals = result.string.split('.')[1]
        result = result.string
        if decimals[-3] == '0':
            result = x[:-2].rstrip('0')
        if decimals[-3] == '9':
            result = x[:-2].rstrip('9')
            try:
                last_digit = int(result[-1])
                result = result[:-1] + str(last_digit + 1)
            except ValueError:
                result = float(result[:-1]) + 1
        return result
    return x


def _logs_exist(fs, path):
    """Do ``fs.exists(path)``, and return ``None`` if it raises ``IOError``"""
    try:
        return fs.exists(path)
    except IOError:
        return None


def uninstall(context):
    """Uninstall script"""


def allowDeletePrincipal(id):
    """True iff this plugin can delete a certain user/group."""


@staticmethod
def get_value(obj):
    """
        Gets a real object value. If object is a wrapper, it unwraps the value behind it.
        Otherwise it returns the same object value.

        :param obj: an object to unwrap.

        :return: an actual (unwrapped) object value.
        """
    return obj


@staticmethod
def prod(tensor, axis=None):
    """Compute the product of a tensor, optionally along an axis.

        Parameters
        ----------
        tensor : tensor
        axis : int, optional
            If provided, the product is computed along this axis.

        Returns
        -------
        out : scalar or tensor
        """
    raise NotImplementedError


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 render_git_describe_long(pieces):
    """TAG-DISTANCE-gHEX[-dirty].

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

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


def remove_lines(lines, remove=('[[back to top]', '<a class="mk-toclify"')):
    """Removes existing [back to top] links and <a id> tags."""
    if not remove:
        return lines[:]
    out = []
    for l in lines:
        if l.startswith(remove):
            continue
        out.append(l)
    return out


@staticmethod
def _parse_channel(channel):
    """Return major and minor channel numbers for given channel"""
    try:
        major, minor = channel.split('-')
    except ValueError:
        major = channel
        minor = 65535
    return major, minor


def _downsample(st, sr):
    """
        Downsampling the MSEED to the designated sampling rate
    """
    for i in range(0, len(st)):
        st[i].decimate(factor=int(st[i].stats.sampling_rate / sr),
            strict_length=False)
    return st


def update_parameters(layers, learning_rate):
    """
    Updates the parameters of the layer

    Arguments:
    layers -- The list with the layers along with the coresponding hyperparameters
    learning_rate -- The learning rate by which the model is learning

    Returns:
    layers -- The updated list with the layers along with the oresponding hyperparameters
    """
    num_layer = len(layers)
    for i in range(num_layer):
        mode = layers[i]['mode']
        if mode == 'pool':
            continue
        elif mode == 'fc' or mode == 'conv':
            layers[i]['W'] = layers[i]['W'] - learning_rate * layers[i]['dW']
            layers[i]['b'] = layers[i]['b'] - learning_rate * layers[i]['db']
        else:
            print('Wrong layer mode in [{}]'.format(i))
    return layers


def last_date_checker(last, end):
    """
    Checks if last and end date are the same.

    :param float last: The last timesteps of the theoretical time axis (from :func:`rebuild_time_axis`)
    :param float end: The numerical date to end (from ``netCDF4.date2num`` or :func:`Date2num`)
    :returns: True if both dates are exactly the same
    :rtype: *boolean*

    """
    if last != end:
        return False
    else:
        return True


@staticmethod
def HowNet():
    """Network that determines how information is integrated across fixations"""
    raise NotImplementedError


def zeta_NH3_Ca_Cl_CB89(T, P):
    """n-c-a: ammonia calcium chloride [CB89]."""
    zeta = -0.00134
    valid = T == 298.15
    return zeta, valid


def _is_dunder(name):
    """Returns True if a __dunder__ name, False otherwise."""
    return name[:2] == name[-2:] == '__' and name[2:3] != '_' and name[-3:-2
        ] != '_' and len(name) > 4


def minDistance(word1, word2):
    """Dynamic programming solution"""
    m = len(word1)
    n = len(word2)
    table = [([0] * (n + 1)) for _ in range(m + 1)]
    for i in range(m + 1):
        table[i][0] = i
    for j in range(n + 1):
        table[0][j] = j
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if word1[i - 1] == word2[j - 1]:
                table[i][j] = table[i - 1][j - 1]
            else:
                table[i][j] = 1 + min(table[i - 1][j], table[i][j - 1],
                    table[i - 1][j - 1])
    return table[-1][-1]


def fibonnaci(a, b, n):
    """
    This function gives a general Fibonnaci series of size n.

    parameters
    ----------
    a: a first real number
    b: a second real number
    n: the size of the Fibonnaci series

    returns
    -------
    A general Fibonnaci series starting from two provided real numbers.

    examples
    --------
    >>> fibonnaci(1,1,10)
    1, 1, 2, 3, 5, 8, 13, 21, 34, 55
    >>> fibonacci(2,2,10)
    2, 2, 4, 6, 10, 16, 26, 42, 68, 110
    """
    series = [int(a), int(b)]
    while n != 0:
        series.append(series[-2] + series[-1])
        n -= 1
    return ', '.join(series)


def _is_sequence(obj):
    """Check if the object is a sequence (list, tuple etc.).

    :param object obj: an object to be checked
    :return: True if the object is iterable but is not a string, False otherwise
    :rtype: bool
    """
    return hasattr(obj, '__iter__') and not isinstance(obj, str)


def end():
    """Returns the timeline date (DateTime) for the content"""


def merge(d1, d2, fn, path=tuple()):
    """
    Updates the dict "d1" with elems of the dict "d2",
    and returns the dict "d1".
    Keys like 'a' and '$a' will be considered equal!
    Collisions will be resolved using the function "fn",
    which takes:
    - both of values
    - link to itself
    - path to values (for ex. ("level1", "level2"))
    end returns new value.
    """
    if not isinstance(d1, dict) or not isinstance(d2, dict):
        raise TypeError('Only dicts can be merged!')
    for k, v in d2.items():
        try:
            if k.startswith('$'):
                variants = k, k[1:]
            else:
                variants = '$' + k, k
        except AttributeError:
            variants = k,
        for key in variants:
            try:
                old_v = d1.pop(key)
            except KeyError:
                continue
            else:
                d1[k] = fn(old_v, v, fn, path + (k,))
                break
        else:
            d1[k] = v
    return d1


def put_parameter(Name=None, Description=None, Value=None, Type=None, KeyId
    =None, Overwrite=None):
    """
    Add one or more paramaters to the system.
    See also: AWS API Documentation

    :example: response = client.put_parameter(
        Name='string',
        Description='string',
        Value='string',
        Type='String'|'StringList'|'SecureString',
        KeyId='string',
        Overwrite=True|False
    )

    :type Name: string
    :param Name: [REQUIRED]
            The name of the parameter that you want to add to the system.

    :type Description: string
    :param Description: Information about the parameter that you want to add to the system

    :type Value: string
    :param Value: [REQUIRED]
            The parameter value that you want to add to the system.

    :type Type: string
    :param Type: [REQUIRED]
            The type of parameter that you want to add to the system.

    :type KeyId: string
    :param KeyId: The parameter key ID that you want to add to the system.

    :type Overwrite: boolean
    :param Overwrite: Overwrite an existing parameter. If not specified, will default to 'false'.

    :rtype: dict
    :return: {}

    :returns:
    (dict) --

    """
    pass


def make_comment(content: str) ->str:
    """Return a consistently formatted comment from the given `content` string.

    All comments (except for "##", "#!", "#:", '#'", "#%%") should have a single
    space between the hash sign and the content.

    If `content` didn't start with a hash sign, one is provided.
    """
    content = content.rstrip()
    if not content:
        return '#'
    if content[0] == '#':
        content = content[1:]
    if content and content[0] not in " !:#'%":
        content = ' ' + content
    return '#' + content


def DeleteInstanceTags(r, instance, tags, dry_run=False):
    """
    Deletes tags from an instance.

    @type instance: str
    @param instance: instance to delete tags from
    @type tags: list of str
    @param tags: tags to delete
    @type dry_run: bool
    @param dry_run: whether to perform a dry run
    """
    query = {'tag': tags, 'dry-run': dry_run}
    return r.request('delete', '/2/instances/%s/tags' % instance, query=query)


def make_iterable(idx):
    """ Simple function to ensure that an argument is iterable"""
    try:
        iter(idx)
    except TypeError:
        if idx is None:
            return []
        else:
            idx = [idx]
    return idx


def set_username():
    """
    Set and validate the username
    :return: string
    """
    username = input('Enter your Oracle Commerce Cloud backend username: ')
    while True:
        if len(username) >= 3:
            return username
        else:
            username = input(
                'Enter your Oracle Commerce Cloud backend username: ')


def is_heating_property(prop, prop_wall):
    """Checks whether or not a fluid side is being heated or cooled, from
    a property of the fluid at the wall and the bulk temperature. Returns True
    for heating the bulk fluid, and False for cooling the bulk fluid.

    Parameters
    ----------
    prop : float
        Viscosity (or Prandtl number) of flowing fluid away from the heat
        transfer surface, [Pa*s]
    prop_wall : float
        Viscosity (or Prandtl number) of the fluid at the wall, [Pa*s]

    Returns
    -------
    is_heating : bool
        Whether or not the flow is being heated up by the wall, [-]

    Examples
    --------
    >>> is_heating_property(1E-3, 1.2E-3)
    False
    """
    return prop_wall < prop


def absolute_latencies(relative_latencies):
    """
    Compute absolute delay + stride for a each in a stack of layers.

    Arguments:
    ----------
    relative_latencies: list of tuples
        each tuple is (rel_delay, rel_stride)

    Returns:
    --------
    absolute_latencies: list of tuples
        each tuple is (abs_stride, abs_stride)

    """
    abs_delay, abs_stride = 0, 1
    absolute_latencies = []
    for idx, (rel_delay, rel_stride) in enumerate(relative_latencies):
        abs_delay += abs_stride * rel_delay
        abs_stride *= rel_stride
        absolute_latencies.append((abs_delay, abs_stride))
    return absolute_latencies


def pin(clear: bool=False):
    """Set/clear selected UV vertices as anchored between multiple unwrap operations

    :param clear: Clear, Clear pinning for the selection instead of setting it
    :type clear: bool
    """
    pass


def orient_single(tm):
    """Compute the T-matrix using a single orientation scatterer.

    Args:
        tm: TMatrix (or descendant) instance

    Returns:
        The amplitude (S) and phase (Z) matrices.
    """
    return tm.get_SZ_single()


def tohex(val, nbits):
    """Utility to convert (signed) integer to hex."""
    return hex((val + (1 << nbits)) % (1 << nbits))


@classmethod
def id_key(cls):
    """ Get the key used to store data ID on an instance

        Override this method to use a different name for 'object_id'
        """
    return cls.__id_key


@staticmethod
def toggle_pause(model, _gui):
    """Pause/unpause simulation."""
    model.toggle_pause()


def _chunk_write(chunk, local_file, progress):
    """Write a chunk to file and update the progress bar."""
    local_file.write(chunk)
    progress.update_with_increment_value(len(chunk))


@classmethod
def get_analyse_model(cls):
    """Set an alternative index in case of period index that not exist yet or alias on several indices.
      This 2 cases make the analyze crash."""
    return


def update_velocities(velocities, accelerations_old, accelerations_new,
    timestep_length):
    """Update the particle velocities using the Velocity-Verlet algoritm.
    Parameters
    ----------
    velocities: (2, N) array_like
        Where N is the number of particles, and the first row are the x
        velocities and the second row the y velocities.
    accelerations: (2, N) array_like
        Where N is the number of particles, and the first row are the x
        accelerations and the second row the y
        accelerations.
    timestep_length: float
        Length for each Velocity-Verlet integration step, in seconds.
    Returns
    -------
    (2, N) array_like:
        Updated velocities.
    """
    velocities[0] += 0.5 * (accelerations_old[0] + accelerations_new[0]
        ) * timestep_length
    velocities[1] += 0.5 * (accelerations_old[1] + accelerations_new[1]
        ) * timestep_length
    return [velocities[0], velocities[1]]


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

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

    """
    pass


def update_package_data(distribution):
    """update build_py options to get package_data changes"""
    build_py = distribution.get_command_obj('build_py')
    build_py.finalize_options()


@classmethod
def serialize(cls, value):
    """Return a string representing the formatted value"""
    raise NotImplementedError


def get_metadata(output, key, mimetype=None):
    """Resolve an output metadata key

    If mimetype given, resolve at mimetype level first,
    then fallback to top-level.
    Otherwise, just resolve at top-level.
    Returns None if no data found.
    """
    md = output.get('metadata') or {}
    if mimetype and mimetype in md:
        value = md[mimetype].get(key)
        if value is not None:
            return value
    return md.get(key)


@classmethod
def _pipeline_prev(cls):
    """
        Identify the previous build step in the build pipeline.
        """
    return cls._ocean._PIPELINE[cls._ocean._PIPELINE.index(cls._PIPELINE[-1
        ]) - 1][1]


def formatdate(now=None, usegmt=False) ->str:
    """
    format time as UTC
    """
    import time
    import datetime
    if not now:
        now = time.time()
    if usegmt:
        dt = datetime.datetime.fromtimestamp(now, datetime.timezone.utc)
    else:
        dt = datetime.datetime.utcfromtimestamp(now)
    zone = '-0000'
    months = {(1): 'Jan', (2): 'Feb', (3): 'Mar', (4): 'Apr', (5): 'May', (
        6): 'Jun', (7): 'Jul', (8): 'Aug', (9): 'Sep', (10): 'Oct', (11):
        'Nov', (12): 'Dec'}
    weeks = {(0): 'Mon', (1): 'Tue', (2): 'Wed', (3): 'Thu', (4): 'Fri', (5
        ): 'Sat', (6): 'Sun'}
    return '{week}, {d} {m} {y} {h}:{M}:{s:02} {zone}'.format(week=weeks.
        get(dt.weekday()), d=dt.day, m=months.get(dt.month), y=dt.year, h=
        dt.hour, M=dt.minute, s=dt.second, zone=zone)


def deconj_dep(token, stop_token=None):
    """
    If a token is conjunct to another token, it gets the "conj" dependency,
    which hides the relationship it has with the token outside of the
    conjunction group. This function traces up all of the "conj" dependencies
    to find that relationship.

    Args:
        token, stop_token: spacy tokens
    Returns:
        a string representing the dependency type
    """
    while token.dep_ in ['conj'] and token.head is not stop_token:
        token = token.head
    return token.dep_


def escapes_sub(match):
    """Substitutes escaped characters."""
    return match.group(1)


def get():
    """
    @api {post} /music/playhistory/get 获取播放历史记录
    @apiVersion 1.0.0
    @apiGroup Playhistory
    @apiDescription 获取播放历史记录

    @apiParam (Headers) {string} token 令牌
    @apiParam (Headers) {String} device_token 设备令牌
    @apiParam (Headers) {String} content_type 内容类型
    @apiParam (Headers) {String} timestamp 时间戳

    @apiSuccess (Success) {Object} itemid 单曲编号
    @apiSuccess (Success) {Object} translatename 翻译名称
    @apiSuccess (Success) {Object} favorite 最爱

    @apiSuccessExample {json} Success-Response:
    [
        {
            "itemid": 1505006,
            "translatename": "Sam歌",
            "favorite": null
        }
    ]
    """


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


def passthrough(result):
    """Simply return the result."""
    return result


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

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

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


def topological_sorting(nodes, edges):
    """
    Return a topologically sorted list of the nodes

    Implemented algorithm from Wikipedia :P

    <http://en.wikipedia.org/wiki/Topological_sorting>

    No error for cyclic edges...
    """
    L = []
    S = nodes[:]
    for node in nodes:
        for es in edges.values():
            if node in es and node in S:
                S.remove(node)
                continue
    while S:
        node = S.pop(0)
        L.append(node)
        node_edges = edges[node]
        while node_edges:
            m = node_edges.pop(0)
            found = False
            for es in edges.values():
                found = m in es
                if found:
                    break
            if not found:
                S.insert(0, m)
    return L


def istest(func):
    """Decorator to mark a function or method as a test
    """
    func.__test__ = True
    return func


def __new__(cls, content, default=None, project=None, option=None):
    """Set endpoint sources."""
    endpoint = str.__new__(cls, content)
    endpoint.default = default
    endpoint.project = project
    endpoint.option = option
    return endpoint


def check_error(child):
    """Raise an error for a problem with a child process."""
    if child.returncode != 0:
        output = (child.stdout + child.stderr).decode('utf-8')
        raise OSError('Problem encountered getting tshark JSON:' + output)


def createReply(title, text, REQUEST, RESPONSE):
    """ Create a reply in the proper place.

        o Returns: HTML (directly or via redirect) # XXX

        o Permission: Reply to item
        """


def get_files(extension='.pck'):
    """Like the 'files' attribute, but accepts an alternative extension.

        Only the files in the queue directory that have a matching extension
        are returned.  Like 'files', the base names of the matching files are
        returned.
        """


def __init__():
    """
        initialize Evolve
        """


def get(name, default=None):
    """Look up the description for a name

        If the named attribute is not defined, the default is
        returned.
        """


def left_shorten(text, width=30, placeholder='...'):
    """
    >>> left_shorten('alongstring', width=8, placeholder='..')
    '..string'

    >>> left_shorten('1234567890', width=12)
    '  1234567890'
    """
    if len(text) > width:
        width -= len(placeholder)
        return f'{placeholder}{text[-width:]}'
    else:
        return f'{text:>{width}}'


def remember(environ, identity):
    """ On egress (no challenge required):

        args -> [ (header-name, header-value), ...] | None

        Return a list of headers suitable for allowing the requesting
        system to remember the identification information (e.g. a
        Set-Cookie header).  Return None if no headers need to be set.
        These headers will be appended to any headers returned by the
        downstream application.
        """


def setmask(arr, x1=None, x2=None):
    """setmask(arr, x1, x2)
    arr = 1D arr
    x1 = lower value
    x2 = upper value
    by default it returns a mask that
    is the full range of arr
    returns
    =======
    mask, x1, x2
    if input x1 and x2 are out of bounds
    then it sets x1 and x2 to the boundry of arr"""
    if (x1 == None) | (x1 <= arr[0]):
        x1 = arr[0]
    if (x2 == None) | (x2 >= arr[-1]):
        x2 = arr[-1]
    mask = (arr >= x1) & (arr <= x2)
    return mask, x1, x2


def deg2HMS(ra=None, dec=None, round=False):
    """ quick and dirty coord conversion. googled to find bdnyc.org.
    """
    RA, DEC, rs, ds = '', '', '', ''
    if dec is not None:
        if str(dec)[0] == '-':
            ds, dec = '-', abs(dec)
        deg = int(dec)
        decM = abs(int((dec - deg) * 60))
        if round:
            decS = int((abs((dec - deg) * 60) - decM) * 60)
        else:
            decS = (abs((dec - deg) * 60) - decM) * 60
        DEC = '{0}{1} {2} {3}'.format(ds, deg, decM, decS)
    if ra is not None:
        if str(ra)[0] == '-':
            rs, ra = '-', abs(ra)
        raH = int(ra / 15)
        raM = int((ra / 15 - raH) * 60)
        if round:
            raS = int(((ra / 15 - raH) * 60 - raM) * 60)
        else:
            raS = ((ra / 15 - raH) * 60 - raM) * 60
        RA = '{0}{1} {2} {3}'.format(rs, raH, raM, raS)
    if ra is not None and dec is not None:
        return RA, DEC
    else:
        return RA or DEC


def translate(message):
    """
    Translate *message* into the current application language.
    The current implementation does nothing, *message* is returned untouched.

    Parameters
    ----------
    message: unicode
        message to translate
    """
    return message


def SELECT_ONE(src_column):
    """
  Builtin aggregator for groupby which selects one row in the group.

  Example: Get one rating row from a user.

  >>> sf.groupby("user",
  ...            {'rating':gl.aggregate.SELECT_ONE('rating')})

  If multiple columns are selected, they are guaranteed to come from the
  same row. for instance:
  >>> sf.groupby("user",
  ...            {'rating':gl.aggregate.SELECT_ONE('rating')},
  ...            {'item':gl.aggregate.SELECT_ONE('item')})

  The selected 'rating' and 'item' value for each user will come from the
  same row in the SFrame.

  """
    return '__builtin__select_one__', [src_column]


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


@classmethod
def _parse_expr(cls, node):
    """Parse a node corresponding to an expression.

        Args:
            node (class Expr): The node describing the expression

        Returns:
            (str) A string containing a fragment of code.
        """
    return cls._parse_value(node.value)


def user_is_valid(user):
    """
    User object validation
    """
    if user is None:
        return False
    if not user.get('id', 0):
        return False
    return True


def p_mul_expr_1(p):
    """MultiplicativeExpr : UnaryExpr"""
    p[0] = p[1]


def extract(fname):
    """Extracts file contents.

    .. warning:: Bytes are returned for Python 3.

    :param str|unicode fname:

    :rtype: bytes|str
    """


@classmethod
def _get_and_info(cls, query):
    """
            Get the "and_" information for query
            - Attaches new "and_" information if not present
            The "and_" information contains depth information for and_ clauses.
            This ensures we can uniquely join tables for "and_" clauses, but
            prevent redundant joins for "or_" clauses.
        :return: "and_" information for query
        """
    if not hasattr(query, 'and_info'):
        setattr(query, 'and_info', {'depth': -1, 'counts': []})
    return getattr(query, 'and_info')


@classmethod
def resolve(cls, status_code: int):
    """
        Resolve the given status code to the corresponding series enum
        :param status_code:
        :return:
        """
    series_code = int(status_code / 100)
    for series in cls:
        if series.value == series_code:
            return series
    return None


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

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

       - arcsinh(default) = default
       - arcsinh(row_sparse) = row_sparse
       - arcsinh(csr) = csr

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

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

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

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


@classmethod
def from_files(cls, files, **options):
    """Create APNG from multiple files.

		This is same as::

			im = APNG()
			for file in files:
				im.append(file, **options)

		:arg list files: A list of file. See :meth:`PNG.open`.
		:arg options: Options for :class:`FrameControl`.
		:rtype: APNG
		"""
    o = cls()
    for file in files:
        o.append(file, **options)
    return o


def resolveValueTokens(tokens, name):
    """Returns an iterable of values for the tokens of the given index
        name"""


def is_downloadable(url):
    """
	Does the url contain a downloadable resource
	"""
    from requests import head
    h = head(url, allow_redirects=True)
    header = h.headers
    content_type = header.get('content-type')
    if 'text' in content_type.lower():
        return False
    if 'html' in content_type.lower():
        return False
    return True


def is_https_live(domain):
    """
    Domain is https live if any https endpoint is live.
    """
    https, httpswww = domain.https, domain.httpswww
    return https.live or httpswww.live


def get_tukeyQcrit2(k, df, alpha=0.05):
    """
    return critical values for Tukey's HSD (Q)

    Parameters
    ----------
    k : int in {2, ..., 10}
        number of tests
    df : int
        degrees of freedom of error term
    alpha : {0.05, 0.01}
        type 1 error, 1-confidence level

    not enough error checking for limitations
    """
    from statsmodels.stats.libqsturng import qsturng
    return qsturng(1 - alpha, k, df)


def merge_proteins(proteins):
    """ Merge all isozymes that catalyze a given reaction.
    Automatically removes all isozymes with missing score.

    Args:
        proteins (pandas.Series): list of proteins

    Returns:
        str: boolean rule

    """
    proteins = set(proteins.dropna())
    if not proteins:
        return None
    gpr_str = ' or '.join(sorted(proteins))
    if len(proteins) > 1:
        return '(' + gpr_str + ')'
    else:
        return gpr_str


def construct_identifier(*args, username_prefix='@'):
    """ Create a post identifier from comment/post object or arguments.

    Examples:

        ::

            construct_identifier('username', 'permlink')
            construct_identifier({'author': 'username', 'permlink': 'permlink'})
    """
    if len(args) == 1:
        op = args[0]
        author, permlink = op['author'], op['permlink']
    elif len(args) == 2:
        author, permlink = args
    else:
        raise ValueError('construct_identifier() received unparsable arguments'
            )
    fields = dict(prefix=username_prefix, author=author, permlink=permlink)
    return '{prefix}{author}/{permlink}'.format(**fields)


def setRange(ax, style):
    """Re-scales the plot to the range stated on the 'style' element.

    Parameters
    ----------
    ax : Matplotlib axes
        Can be obtained from a figure with: fig.get_axes()[0]
    style : Plot-style dictionary.
        Should contain:
            style['xRange'] = (lo, hi)
            style['yRange'] = (lo, hi)

    Returns
    -------
    ax
        Returns the changed ax with the modification performed.

    """
    ax.set_xlim(style['xRange'][0], style['xRange'][1])
    ax.set_ylim(style['yRange'][0], style['yRange'][1])
    return ax


def is_iterable(obj):
    """
    Are we being asked to look up a list of things, instead of a single thing?
    We check for the `__iter__` attribute so that this can cover types that
    don't have to be known by this module, such as NumPy arrays.

    Strings, however, should be considered as atomic values to look up, not
    iterables. The same goes for tuples, since they are immutable and therefore
    valid entries.

    We don't need to check for the Python 2 `unicode` type, because it doesn't
    have an `__iter__` attribute anyway.
    """
    return hasattr(obj, '__iter__') and not isinstance(obj, str
        ) and not isinstance(obj, tuple)


def post_run_create(sender, instance, raw, **kwargs):
    """
    Post action after creating a run instance.

    This will make sure the ``schedule_id`` field is set.

    """
    if not instance.schedule_id:
        instance.schedule_id = instance.id
        instance.save()


def dict_merge(*dicts):
    """
    Merge all provided dicts into 1 dict.
    """
    merged = {}
    for d in dicts:
        if not isinstance(d, dict):
            raise ValueError('Value should be of dict type')
        else:
            merged.update(d)
    return merged


def assoc(k, v, orig):
    """Given an original dictionary orig, return a cloned dictionary with `k` set to `v`"""
    out = orig.copy()
    out[k] = v
    return out


def is_basicaer_provider(backend):
    """Detect whether or not backend is from BasicAer provider.

    Args:
        backend (BaseBackend): backend instance
    Returns:
        bool: True is BasicAer
    """
    from qiskit.providers.basicaer import BasicAerProvider
    return isinstance(backend.provider(), BasicAerProvider)


def write_character_file(name, ks, energies, characters, n_bands, n_k):
    """ Create a file containing columns of kx, ky, kz, E and the character
    of a specific band (the name of which should be reflected in the
    filename). """
    fmt = '{: .10f} '
    s = '{:>10} ' + 5 * fmt + '\n'
    header = '#{:>9}' + 5 * '{:>14}' + '\n'
    header = header.format('k index', 'kx (pi/a)', 'ky (pi/b)', 'kz (pi/c)',
        'E (eV)', 'character %')
    with open(name, 'w+') as f:
        f.write(header)
        for band in range(n_bands):
            f.write('# Band {}\n'.format(band))
            for k in range(n_k):
                i = band * n_k + k
                line = s.format(k, ks[k][0], ks[k][1], ks[k][2], energies[i
                    ], characters[i])
                f.write(line)


def operator_cheat_sheet():
    """List all the Operators in a text-block, useful for scripting

    """
    pass


def count_status(all_parsed_status):
    """return count of status"""
    result = {}
    for parsed_status in all_parsed_status:
        value = parsed_status['value']
        if not value in result:
            result[value] = 0
        result[value] = result[value] + 1
    return result


def _toOperation(info, resource, handler):
    """
    Augment route info, returning a Swagger-compatible operation description.
    """
    operation = dict(info)
    operation['tags'] = [resource]
    if 'operationId' not in operation:
        operation['operationId'] = str(resource) + '_' + handler.__name__
    return operation


@staticmethod
def _list_replace_ci(lst, replace, replacement):
    """
        Replace all values case-insensitive-matching values in-line in a list.  Return whether any
        values were replaced.
        """
    replaced = False
    for i, v in enumerate(lst):
        if v.lower() == replace.lower():
            lst[i] = replacement
            replaced = True
    return replaced


def strip_last_filename_from_url(url, sep='/'):
    """Given a url with a filename at the end, strip the last part off of the
    url and return the previous segment. If the seperator can't be located,
    this method will return the unmodified url.

    > strip_last_filename_from_ur("http://utldr.co/s/document.html")
    > "http://utldr.co/s/"

    :param url: The url to trim the filename off of.
    :type url: str.
    :param sep: (optional) Seperator to use when splitting the filename.

    :returns: The url with the last filename chopped off.
    :rtype: str.
    """
    path = ''.join(reversed(url))
    index = path.find(sep)
    if index == -1:
        return url
    return ''.join(reversed(path[index:]))


def paste(selection: bool=False):
    """Paste text from clipboard

    :param selection: Selection, Paste text selected elsewhere rather than copied (X11 only)
    :type selection: bool
    """
    pass


def remove_surrogates(s, errors='replace'):
    """Replace surrogates generated by fsdecode with '?'
    """
    return s.encode('utf-8', errors).decode('utf-8')


@classmethod
def password_from_settings(cls, settings):
    """Return the hashed password from the tornado settings.

        If there is no configured password, an empty string will be returned.
        """
    return settings.get('password', u'')


@classmethod
def from_edges(cls, edges):
    """Form a Graph instance from the given {from: (to1, to2)} dict.

        The given 'edges' dictionary includes a key for each node from
        which a transition might originate. The corresponding value is
        either a node or a tuple of nodes; the graph includes an edge
        from the key node to each node in the value. For example, the
        dict {"A": "B", "B", ("C", "D")} defines 3 edges: A to B,
        B to C and B to D.
        """
    if edges is None:
        edges = {}
    states = set()
    distances = {}
    next = {}
    for k, v in edges.items():
        states.add(k)
        distances[k, k] = 0
        if not isinstance(v, (list, tuple)):
            v = v,
        for s in v:
            states.add(s)
            distances[k, s] = 1
            next[k, s] = s
    for k in states:
        for i in states:
            for j in states:
                segment1 = distances.get((i, k))
                if segment1 is None:
                    continue
                segment2 = distances.get((k, j))
                if segment2 is None:
                    continue
                candidate_distance = segment1 + segment2
                curpair = i, j
                current_distance = distances.get(curpair)
                if (current_distance is None or current_distance >
                    candidate_distance):
                    distances[curpair] = candidate_distance
                    next[curpair] = next.get((i, k), k)
    return cls(next)


def clean_whitespace(chatbot, statement):
    """
    Remove any consecutive whitespace characters from the statement text.
    """
    import re
    statement.text = statement.text.replace('\n', ' ').replace('\r', ' '
        ).replace('\t', ' ')
    statement.text = statement.text.strip()
    statement.text = re.sub(' +', ' ', statement.text)
    return statement


def CDLSEPARATINGLINES(df):
    """
    Separating Lines
    """


def filterable():
    """ Returns a vocabulary for filtering the column or None if no filtering is available
        """


def transform_image_mask_white(val):
    """Will convert any pixel value of 0 (white) to 255 for wordcloud mask."""
    if val == 0:
        return 255
    else:
        return val


def get_arraytype():
    """pygame.sndarray.get_arraytype (): return str

    DEPRECATED - only numpy arrays are now supported.
    """
    return 'numpy'


def get_uri():
    """Return the URI string corresponding to the strongest cap associated
        with this node. If this node is read-only, the URI will only offer
        read-only access. If this node is read-write, the URI will offer
        read-write access.

        If you have read-write access to a node and wish to share merely
        read-only access with others, use get_readonly_uri().
        """


def view_frame():
    """Reset viewable area to show range around current frame

    """
    pass


@staticmethod
def _reduce(res, result_single_frame):
    """ 'add' action for an accumulator"""
    if isinstance(res, list) and len(res) == 0:
        res = result_single_frame
    else:
        res += result_single_frame
    return res


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 get_dict(cls, key_field, *fields):
    """
        Retrieve as dict of {key_field: *fields} mapping. If `fields` is single value, returns `{key:value}` mapping.
                If `fields` is **tuple**, returns `{key: (tuple of fields value)}` mapping.
        :param key_field: name of Option field for dict key. Only `code` and `name` are available.
        :param fields: Names of Option field for values. Can be tuple or single value. Impact value part of return dict.
        :return: dict of {key_field: *fields} mapping.
        """
    if key_field not in ['code', 'name']:
        raise NameError(
            "'%s' is not correct key field. Only 'code' and 'name' can be key field."
             % str(key_field))
    if len(fields) == 0:
        raise ValueError('No fields argument found.')
    found_fields = set()
    for f in fields:
        if f not in ['code', 'name', 'text']:
            raise NameError(
                "'%s' is incorrect Option field. Only 'code', 'name' and 'text' are available."
                 % str(f))
        if f in found_fields:
            raise ValueError("Duplicated fields '%s' found." % str(f))
        found_fields.add(f)
    items = {}
    for o in cls.__get_name_options_mapping().values():
        key = getattr(o, key_field)
        value = []
        for f in fields:
            value.append(getattr(o, f))
        items[key] = value[0] if len(value) == 1 else tuple(value)
    return items


def RGB_to_color(r, g, b):
    """Convert three 8-bit red, green, blue component values to a single 24-bit
    color value.
    """
    return (r & 255) << 16 | (g & 255) << 8 | b & 255


def build_no_log_generator(container, log_args):
    """Return a generator that prints a warning about logs and waits for
    container to exit.
    """
    yield "WARNING: no logs are available with the '{}' log driver\n".format(
        container.log_driver)


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

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

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


def split_by_n(seq, n):
    """A generator to divide a sequence into chunks of n units.
       src: http://stackoverflow.com/questions/9475241/split-python-string-every-nth-character"""
    while seq:
        yield seq[:n]
        seq = seq[n:]


def __call__():
    """Execute the rule or rule element.

        If this method returns False, execution will stop. If it returns True,
        execution will continue if possible.
        """


@staticmethod
def _actual_phy(dphy, bit):
    """Return the actual output phase.
        Due to the resolution of the DDS, the actual output phase
        may be (a bit) different than the queried.
        :param dphy: Phase register value (int).
        :param bit: Number of bits used for the phase resolution (int)
        :returns: Actual output phase offset in degree (float).
        """
    return float(360 * dphy) / (1 << bit)


@classmethod
def to_yaml(cls, dumper, data):
    """
        Convert a Python object to a representation node.
        """
    return dumper.represent_scalar('tag:yaml.org,2002:int', '{:04o}'.format
        (data._value))


def pep440_version(version):
    """Normalize version to PEP 440 standards"""
    from .vendor.pip_shims.shims import parse_version
    return str(parse_version(version))


@classmethod
def sql_schema(cls, *args, **kwargs):
    """
        Generate the base table schema for the main GlycanRecord table.

        Parameters
        ----------
        inherits: dict
            Metadata extensions to include in the table schema

        Yields
        ------
        str:
            An SQL script block describing the GlycanRecord table. Descendants
            may yield additional statements.
        """
    ext_stmts = []
    meta_map = dict(cls.__column_data_map)
    meta_map.update(kwargs.get('inherits', {}))
    for name, type_transformer in meta_map.items():
        template = '{name} {type}\n'.format(name=name, type=type_transformer[0]
            )
        ext_stmts.append(template)
    ext_def = ', '.join(ext_stmts)
    if len(ext_def) > 0:
        ext_def = ', ' + ext_def
    schema = cls.__table_schema__.format(table_name=cls.table_name)
    schema = schema.replace('/*rest*/', ext_def)
    yield schema


def _check_as_tuple(check):
    """Translate a check into a tuple of app, name, conclusion"""
    app = check.get('app')
    if app:
        slug = app.get('slug')
    else:
        slug = 'Unknown'
    name = check.get('name')
    conclusion = check.get('conclusion')
    return slug, name, conclusion


def df_percentage(row, column_label, total):
    """
	Returns the value of the specified column as a percentage of the given total
	The total is usually the sum of the specified column

	Do not call this function directly; use it with df.apply() instead.

	data_frame["Bob Percentage"] = data_frame.apply(df_percentage, args=(
				13, "Bob"), axis=1)

	:param row: row of the data frame
	:type row: pandas.core.series.Series
	:param column_label: column label to calculate percentage for
	:type column_label: str
	:param total: total value
	:type column_label: str

	:return: Percentage * 100
	:rtype: float
	"""
    return row[column_label] / float(total) * 100.0


def expand_abbreviations(template, abbreviations):
    """Expand abbreviations in a template name.

    :param template: The project template name.
    :param abbreviations: Abbreviation definitions.
    """
    if template in abbreviations:
        return abbreviations[template]
    prefix, sep, rest = template.partition(':')
    if prefix in abbreviations:
        return abbreviations[prefix].format(rest)
    return template