def get_many_text(items, one, two, many):
    """Get the right text based on the number of ``items``."""
    message = ''
    if not items:
        return message
    items_count = len(items)
    if items_count == 1:
        message = one.format(item=items[0])
    elif items_count == 2:
        message = two.format(first=items[0], second=items[1])
    else:
        left = ', '.join(items[:-1])
        last = items[-1]
        message = many.format(left=left, last=last)
    return message


def _first(x):
    """return the first item of the supplied Series"""
    return x.iloc[0]


def _footer(settings):
    """
    Return the footer of the Latex document.

    Returns:
        tex_footer_str (string): Latex document footer.
    """
    return '\n\n\\end{tikzpicture}\n\\end{document}'


@staticmethod
def __construct_recipient_agreement_request(recipients):
    """ Takes a list of :class:`Recipients <pyEchosign.classes.users.Recipient>` and returns the JSON required by
        the Echosign API.

        Args:
            recipients: A list of :class:`Recipients <pyEchosign.classes.users.Recipient>`

        """
    recipient_set = []
    for recipient in recipients:
        recipient_info = dict(email=recipient.email)
        recipient_set_info = dict(recipientSetMemberInfos=recipient_info,
            securityOptions=[dict(authenticationMethod='', password=
            'CONTENT FILTERED', phoneInfos=[dict(phone='', countryCode='')]
            )], recipientSetRole='SIGNER')
        recipient_set.append(recipient_set_info)
    return recipient_set


def is_factor(obj):
    """ Is obj a Factor?
    """
    return hasattr(obj, '_factor_flag')


def scale_voltage_current_power(data, voltage=1, current=1):
    """
    Scales the voltage, current, and power of the DataFrames
    returned by :py:func:`singlediode` and :py:func:`sapm`.

    Parameters
    ----------
    data: DataFrame
        Must contain columns `'v_mp', 'v_oc', 'i_mp' ,'i_x', 'i_xx',
        'i_sc', 'p_mp'`.
    voltage: numeric, default 1
        The amount by which to multiply the voltages.
    current: numeric, default 1
        The amount by which to multiply the currents.

    Returns
    -------
    scaled_data: DataFrame
        A scaled copy of the input data.
        `'p_mp'` is scaled by `voltage * current`.
    """
    data = data.copy()
    voltages = ['v_mp', 'v_oc']
    currents = ['i_mp', 'i_x', 'i_xx', 'i_sc']
    data[voltages] *= voltage
    data[currents] *= current
    data['p_mp'] *= voltage * current
    return data


def merge_periods(data):
    """
    Merge periods to have better continous periods.
    Like 350-450, 400-600 => 350-600

    :param data: list of periods
    :type data: list
    :return: better continous periods
    :rtype: list
    """
    newdata = sorted(data, key=lambda drange: drange[0])
    end = 0
    for period in newdata:
        if period[0] != end and period[0] != end - 1:
            end = period[1]
    dat = newdata
    new_intervals = []
    cur_start = None
    cur_end = None
    for dt_start, dt_end in dat:
        if cur_end is None:
            cur_start = dt_start
            cur_end = dt_end
            continue
        elif cur_end >= dt_start:
            cur_end = dt_end
        else:
            new_intervals.append((cur_start, cur_end))
            cur_start = dt_start
            cur_end = dt_end
    new_intervals.append((cur_start, cur_end))
    return new_intervals


def collect_prerequisites():
    """
    Collects all prerequisites required to run the UIAutomation test case.
    :return:
    """
    print('1 - iOS')
    print('2 - Android')
    platform = int(input('Choose platform:'))
    if 1 < platform > 2:
        print('You have selected an invalid platform')
        exit(1)
    app_bundle = input('Enter path to app bundle:')
    if app_bundle.__len__() == 0:
        print('Can not test an app which does not exist ;)')
        exit(1)
    return {'platform': platform, 'app_bundle': app_bundle}


def from_set_to_list(ref, tab):
    """Convert set into a list

    Used for the retention store

    :param ref: Not used
    :type ref:
    :param tab: list to parse
    :type tab: list
    :return: list of names
    :rtype: list
    """
    return list(tab)


def select_linked_to():
    """Select nodes linked to the selected ones

    """
    pass


def sanitize(catalog):
    """This simply calls the catalog function that performs this task.
    """
    catalog.sanitize()
    catalog.save_caches()
    return


def _const_compare_digest_backport(a, b):
    """
    Compare two digests of equal length in constant time.

    The digests must be of type str/bytes.
    Returns True if the digests match, and False otherwise.
    """
    result = abs(len(a) - len(b))
    for l, r in zip(bytearray(a), bytearray(b)):
        result |= l ^ r
    return result == 0


@classmethod
def pre_load_plugin(cls, name, plugin):
    """Pre-loads the specified plugin

        Adds the plugin to the pre-loaded plugins static map

        :param name: The name of the plugin
        :type name: str
        :param plugin: The plugin to load
        :type plugin: obj
        """
    cls._pre_loaded_plugins[name] = plugin


def three_partition(x):
    """partition a set of integers in 3 parts of same total value

    :param x: table of non negative values
    :returns: triplet of the integers encoding the sets, or None otherwise
    :complexity: :math:`O(2^{2n})`
    """
    f = [0] * (1 << len(x))
    for i in range(len(x)):
        for S in range(1 << i):
            f[S | 1 << i] = f[S] + x[i]
    for A in range(1 << len(x)):
        for B in range(1 << len(x)):
            if A & B == 0 and f[A] == f[B] and 3 * f[A] == f[-1]:
                return A, B, (1 << len(x)) - 1 ^ A ^ B
    return None


def _inject_mutations_2D(phi, dt, xx, yy, theta0, frozen1, frozen2, nomut1,
    nomut2):
    """
    Inject novel mutations for a timestep.
    """
    if not frozen1 and not nomut1:
        phi[1, 0] += dt / xx[1] * theta0 / 2 * 4 / ((xx[2] - xx[0]) * yy[1])
    if not frozen2 and not nomut2:
        phi[0, 1] += dt / yy[1] * theta0 / 2 * 4 / ((yy[2] - yy[0]) * xx[1])
    return phi


def convert2boolean(arg):
    """convert2boolean is used for environmental variables
    that must be returned as boolean"""
    if not isinstance(arg, bool):
        return arg.lower() in ('yes', 'true', 't', '1', 'y')
    return arg


def is_nonnegative_int(value):
    """
    Verify that value is None or a positive int.

    Parameters
    ----------
    value : None or int
            The `value` to be checked.

    Raises
    ------
    ValueError
        When the value is not None or is a negative integer
    """
    if value is None:
        return
    elif isinstance(value, int):
        if value >= 0:
            return
    msg = 'Value must be a nonnegative integer or None'
    raise ValueError(msg)


def direct(zelf, txt):
    """ output txt directly. """
    if '_socket' in zelf:
        try:
            zelf._socket.write(txt)
        except TypeError:
            zelf._socket.write(str(txt))
        zelf._socket.write('\n')
        zelf._socket.flush()
    else:
        zelf.say_id(zelf.id(), zelf.channel, txt)


def hbytes(val):
    """Return pair value and unit."""
    unit = '', 'k', 'M', 'G', 'T', 'P'
    u = 0
    while val > 1000 and u < len(unit):
        u += 1
        val = val / 1024.0
    return val, unit[u]


def _table_columns(first_table_row):
    """Find column ranges in output line.

    Return list of tuples (start,end) for each column
    detected by plus (+) characters in delimiter line.
    """
    positions = []
    start = 1
    while start < len(first_table_row):
        end = first_table_row.find('+', start)
        if end == -1:
            break
        positions.append((start, end))
        start = end + 1
    return positions


def str2var(s, variables):
    """Try to match string `s` to one of the `Var`s in `variables`."""
    for variable in variables:
        if s == str(variable):
            return variable
    raise ValueError(s)


def _clean_tag(tag):
    """remove namespace in the tag"""
    return tag.split('}')[1][:] if '}' in tag else tag


@classmethod
def register(cls, algorithm_name: str, mutation_class):
    """Register a class with a string key."""
    cls.REGISTRY[algorithm_name] = mutation_class
    return mutation_class


@staticmethod
def apply(f, args=(), kwargs=None):
    """Apply a function.

        Parameters
        ----------
        f : callable
            The function to call.
        args : tuple, optional
            The positional arguments.
        kwargs : dict, optional
            The keyword arguments.

        Returns
        -------
        result : any
            f(*args, **kwargs)
        """
    return f(*args, **kwargs or {})


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 dynamic(cls, binding_str):
    """Parse dynamic port forwarding binding string to dict."""
    return cls._parse(cls.dynamic_pf_re, binding_str)


@classmethod
def get_source_display(cls, oid):
    """
        Returns the text to display when showing a Ref pointing to the object of type cls with
        the id oid.

        This is used by Connection relations' GUI.
        """
    return oid


def ngrams(n, tokens):
    """
    Function returning an iterator over the given sequence's n-grams. The
    type of yielded n-grams will match the sequence's one.

    Args:
        n (number): size of the subsequences.
        tokens (iterable): token sequence, should support random access.

    Yields:
        tuple or string: A n-gram.

    """
    limit = len(tokens) - n + 1
    for i in range(limit):
        yield tokens[i:i + n]


def getCandidateLocalRoles(obj):
    """ Return a sequence local roles assignable by the current user for
            a given object.

        o 'obj' is the object to which role assignments may be made.

        o Permission:  Public # ????
        """


def file_name(path: str) ->str:
    """From path of a file, find the name of that file"""
    for i in range(len(path) - 1, 0, -1):
        if path[i] == '/' or path[i] == '\\':
            return path[i + 1:]
    else:
        return path


def get_current_canvas():
    """ Proxy for context.get_current_canvas to avoud circular import.
    This function replaces itself with the real function the first
    time it is called. (Bah)
    """
    from .context import get_current_canvas
    globals()['get_current_canvas'] = get_current_canvas
    return get_current_canvas()


def pprint_path(path):
    """
    print information of a pathlib / os.DirEntry() instance with all "is_*" functions.
    """
    print('\n*** %s' % path)
    for attrname in sorted(dir(path)):
        if attrname.startswith('is_'):
            value = getattr(path, attrname)
            print('%20s: %s' % (attrname, value))
    print()


def creatable(method, payment_type, separate):
    """If it's possible to create new payments of this payment method type

        :param method: payment method
        :param payment_type: kind of payment
        :param separate: if it's created separately from a sale/purchase
        :returns: True if you can create new methods of this type
        """


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

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


def _calc_num_bins(binsize, t_start, t_stop):
    """
    Calculates the number of bins from given parameters.

    Calculates the number of bins `num_bins` from the three parameters
    `binsize`, `t_start`, `t_stop`.

    Parameters
    ----------
    binsize : pq.Quantity
        Size of Bins
    t_start : pq.Quantity
        Start time
    t_stop : pq.Quantity
        Stop time

    Returns
    -------
    num_bins : int
       Number of bins calculated from given parameters.

    Raises
    ------
    ValueError
        When `t_stop` is smaller than `t_start`".

    """
    if binsize is not None and t_start is not None and t_stop is not None:
        if t_stop < t_start:
            raise ValueError('t_stop (%s) is smaller than t_start (%s)' % (
                t_stop, t_start))
        return int(((t_stop - t_start).rescale(binsize.units) / binsize).
            magnitude)


def describe_volume_status(DryRun=None, VolumeIds=None, Filters=None,
    NextToken=None, MaxResults=None):
    """
    Describes the status of the specified volumes. Volume status provides the result of the checks performed on your volumes to determine events that can impair the performance of your volumes. The performance of a volume can be affected if an issue occurs on the volume's underlying host. If the volume's underlying host experiences a power outage or system issue, after the system is restored, there could be data inconsistencies on the volume. Volume events notify you if this occurs. Volume actions notify you if any action needs to be taken in response to the event.
    The DescribeVolumeStatus operation provides the following information about the specified volumes:
    See also: AWS API Documentation

    Examples
    This example describes the status for the volume vol-1234567890abcdef0.
    Expected Output:
    This example describes the status for all volumes that are impaired. In this example output, there are no impaired volumes.
    Expected Output:

    :example: response = client.describe_volume_status(
        DryRun=True|False,
        VolumeIds=[
            'string',
        ],
        Filters=[
            {
                'Name': 'string',
                'Values': [
                    'string',
                ]
            },
        ],
        NextToken='string',
        MaxResults=123
    )

    :type DryRun: boolean
    :param DryRun: Checks whether you have the required permissions for the action, without actually making the request, and provides an error response. If you have the required permissions, the error response is DryRunOperation . Otherwise, it is UnauthorizedOperation .

    :type VolumeIds: list
    :param VolumeIds: One or more volume IDs.
            Default: Describes all your volumes.
            (string) --

    :type Filters: list
    :param Filters: One or more filters.
            action.code - The action code for the event (for example, enable-volume-io ).
            action.description - A description of the action.
            action.event-id - The event ID associated with the action.
            availability-zone - The Availability Zone of the instance.
            event.description - A description of the event.
            event.event-id - The event ID.
            event.event-type - The event type (for io-enabled : passed | failed ; for io-performance : io-performance:degraded | io-performance:severely-degraded | io-performance:stalled ).
            event.not-after - The latest end time for the event.
            event.not-before - The earliest start time for the event.
            volume-status.details-name - The cause for volume-status.status (io-enabled | io-performance ).
            volume-status.details-status - The status of volume-status.details-name (for io-enabled : passed | failed ; for io-performance : normal | degraded | severely-degraded | stalled ).
            volume-status.status - The status of the volume (ok | impaired | warning | insufficient-data ).
            (dict) --A filter name and value pair that is used to return a more specific list of results. Filters can be used to match a set of resources by various criteria, such as tags, attributes, or IDs.
            Name (string) --The name of the filter. Filter names are case-sensitive.
            Values (list) --One or more filter values. Filter values are case-sensitive.
            (string) --

    :type NextToken: string
    :param NextToken: The NextToken value to include in a future DescribeVolumeStatus request. When the results of the request exceed MaxResults , this value can be used to retrieve the next page of results. This value is null when there are no more results to return.

    :type MaxResults: integer
    :param MaxResults: The maximum number of volume results returned by DescribeVolumeStatus in paginated output. When this parameter is used, the request only returns MaxResults results in a single page along with a NextToken response element. The remaining results of the initial request can be seen by sending another request with the returned NextToken value. This value can be between 5 and 1000; if MaxResults is given a value larger than 1000, only 1000 results are returned. If this parameter is not used, then DescribeVolumeStatus returns all results. You cannot specify this parameter and the volume IDs parameter in the same request.

    :rtype: dict
    :return: {
        'VolumeStatuses': [
            {
                'VolumeId': 'string',
                'AvailabilityZone': 'string',
                'VolumeStatus': {
                    'Status': 'ok'|'impaired'|'insufficient-data',
                    'Details': [
                        {
                            'Name': 'io-enabled'|'io-performance',
                            'Status': 'string'
                        },
                    ]
                },
                'Events': [
                    {
                        'EventType': 'string',
                        'Description': 'string',
                        'NotBefore': datetime(2015, 1, 1),
                        'NotAfter': datetime(2015, 1, 1),
                        'EventId': 'string'
                    },
                ],
                'Actions': [
                    {
                        'Code': 'string',
                        'Description': 'string',
                        'EventType': 'string',
                        'EventId': 'string'
                    },
                ]
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


def get_span_vectors(normal, c, d):
    """ get_span_vectors(normal, prevA, prevB) -> (a,b)

    Given a normal, return two orthogonal vectors which are both
    orthogonal to the normal. The vectors are calculated so they match
    as much as possible the previous vectors.
    """
    a1 = d.cross(normal)
    if a1.norm() < 0.001:
        b1 = c.cross(normal)
        a1 = b1.cross(normal)
    a2 = -1 * a1
    if c.distance(a1) > c.distance(a2):
        a1 = a2
    b1 = a1.cross(normal)
    b2 = -1 * b1
    if d.distance(b1) > d.distance(b2):
        b1 = b2
    return a1.normalize(), b1.normalize()


def delete_loose(use_verts: bool=True, use_edges: bool=True, use_faces:
    bool=False):
    """Delete loose vertices, edges or faces

    :param use_verts: Vertices, Remove loose vertices
    :type use_verts: bool
    :param use_edges: Edges, Remove loose edges
    :type use_edges: bool
    :param use_faces: Faces, Remove loose faces
    :type use_faces: bool
    """
    pass


@classmethod
def get_agent(cls, ID):
    """Return utility agent with given ID."""
    for agent in (cls.heating_agents + cls.cooling_agents):
        if agent.ID == ID:
            return agent
    raise KeyError(ID)


@classmethod
def set_image(cls, value, category):
    """
        sets the default image for a specific category.
        :param value: the image uuid or name
        :param category: the category
        :return:
        """
    cls.set('image', value, category=category)


def __repr__():
    """Returns a string identifier of the directory."""


def is_user_context(context):
    """Indicates if the request context is a normal user."""
    if not context:
        return False
    if context.is_admin:
        return False
    if not context.user_id or not context.project_id:
        return False
    return True


def enforce_placement_group():
    """Enforces all tasks to be launched into placement group."""
    global enforce_placement_group_val
    enforce_placement_group_val = True


def update_parameter(store, name, value):
    """Updates the parameter in the database.

    The callsite should convert the value properly
    """
    store.execute(
        """UPDATE parameter_data
                    SET field_value = ?
                    WHERE field_name = ?"""
        , (value, name))


def IGNORE_FAKE(s, t, v):
    """Only events with actual value (!=None) pass"""
    if v is not None:
        return s, t, v
    else:
        return None


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

        :param SharedFolderMountDetails val:
        :rtype: EventDetails
        """
    return cls('shared_folder_mount_details', val)


def delete_pyc_file(python_script):
    """
    Deletes the .pyc file that corresponds to the given .py file
    :param python_script: str
    """
    from tpPyUtils import path, fileio
    script_name = path.get_basename(python_script)
    if not python_script.endswith('.py'):
        print('WARNING: Could not delete .pyc file for {}!'.format(script_name)
            )
        return
    compile_script = python_script + 'c'
    if path.is_file(compile_script):
        compile_name = path.get_basename(compile_script)
        compile_dir_name = path.get_dirname(compile_script)
        if not compile_name.endswith('.pyc'):
            return
        fileio.delete_file(name=compile_name, directory=compile_dir_name)


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


def _get_formatter():
    """
    Get the string of log formatter.

    Returns:
        str, the string of log formatter.
    """
    formatter = (
        '[%(levelname)s] %(sub_module)s(%(process)d:%(thread)d,%(processName)s):%(asctime)s [%(filepath)s:%(lineno)d] %(message)s'
        )
    return formatter


def manage_deleteGroups(dns=[], REQUEST=None):
    """ Delete groups specified by a list of group DN strings which are
        handed in as the *dns* argument.

        Permission: *Manage users*
        """


def generate_unspliced_fasta(fasta_path, gtf_path, out_path):
    """Generate a unspliced FASTA using the genome and GTF.

    This function assumes the order in which the chromosomes appear in the
    genome FASTA is identical to the order in which they appear in the GTF.
    Additionally, the GTF must be sorted by start position.
    The spliced FASTA contains entries of length 2 * (k - 1) for k = 31,
    centered around exon-intron splice junctions + full introns
    (any overlapping regions are collapsed).

    :param fasta_path: path to genomic FASTA file
    :type fasta_path: str
    :param gtf_path: path to GTF file
    :type gtf_path: str
    :param out_path: path to unspliced FASTA to generate
    :type out_path: str

    :return: path to generated unspliced FASTA
    :rtype: str
    """
    pass


def isFallbackActive():
    """Decide whether to switch to the fallback theme, or not."""


@classmethod
def _check_hours_input(cls, hours):
    """Check input hours are correct."""
    hours = hours.split('-')
    try:
        correct = sum(list(map(int, hours))) < 13 and len(hours) == 4
    except ValueError:
        correct = False
    except IndexError:
        correct = False
    return correct


def __new__(cls, rargname, post):
    """
        Create new instance, forcing strings to be uppercase
        """
    if isinstance(rargname, str):
        rargname = rargname.upper()
    if isinstance(post, str):
        post = post.upper()
    return super().__new__(cls, rargname, post)


def grid():
    """
        show the grid cells on the game canvas
    """
    global show_grid
    show_grid = True


def ParseBool(text):
    """Parse a boolean value.

  Args:
    text: Text to parse.

  Returns:
    Boolean values parsed

  Raises:
    ValueError: If text is not a valid boolean.
  """
    if text in ('true', 't', '1'):
        return True
    elif text in ('false', 'f', '0'):
        return False
    else:
        raise ValueError('Expected "true" or "false".')


def generate_subject(softwarerelease, osversion):
    """
    Generate message subject.

    :param softwarerelease: Software version.
    :type softwarerelease: str

    :param osversion: OS version.
    :type osversion: str
    """
    return 'SW {0} - OS {1} available!'.format(softwarerelease, osversion)


def _resize_last(splitter, fraction=4):
    """
    Resize the splitter making the last widget in it 1/fraction the height of it, and the preceding
    widgets share the remaining space equally.
    :param splitter: QSplitter to be resized.
    :param fraction: Integer.
    :return:
    """
    sizes = splitter.sizes()
    total_height = sum(sizes)
    num_widgets = len(sizes)
    height_last = total_height // fraction
    height_rest = total_height * (fraction - 1) // fraction
    new_sizes = [height_rest for i in range(num_widgets - 1)]
    new_sizes.append(height_last)
    splitter.setSizes(new_sizes)


@classmethod
def refine(cls, itemty):
    """Refine to a precise list type
        """
    res = cls(itemty)
    assert res.is_precise()
    return res


def make_ident(method, route):
    """
    For the time being, if a path ends in '/', it expects an argument to follow
    """
    parts = route.rstrip('/1234567890.cu')
    return method + '->' + parts


@classmethod
def get_pseudopotential_type(cls, calc, **kwargs):
    """Return a list of pseudopotential types.

        List MUST be sorted by atom types.
        """
    types = []
    raw_types = cls._get_raw_pseudopotential_type(calc, **kwargs)
    for element in sorted(raw_types):
        if raw_types[element] is None or raw_types[element
            ] in cls._pseudopotential_types:
            types.append(raw_types[element])
        else:
            types.append('other')
    return types


def _check_info(info, sss=True, tsss=True, calibration=True, ctc=True):
    """Ensure that Maxwell filtering has not been applied yet."""
    for ent in info['proc_history']:
        for msg, key, doing in (('SSS', 'sss_info', sss), ('tSSS', 'max_st',
            tsss), ('fine calibration', 'sss_cal', calibration), (
            'cross-talk cancellation', 'sss_ctc', ctc)):
            if not doing:
                continue
            if len(ent['max_info'][key]) > 0:
                raise RuntimeError(
                    'Maxwell filtering %s step has already been applied, cannot reapply'
                     % msg)


def binary_reduce(reducer, binary_op, graph, lhs, rhs, lhs_data, rhs_data,
    out_size, lhs_map, rhs_map, out_map):
    """Perform binary operation between given data and reduce based on graph
    structure.

    Parameters
    ----------
    reducer : str
        Type of reduction: 'sum', 'max', 'min', 'mean', 'prod', 'none' (no
        reduction)
    binary_op : str
        Binary operation to perform, can be 'add', 'mul', 'sub', 'div'
    graph : GraphIndex
        The graph
    lhs : int
        The lhs target (src, dst, edge)
    rhs : int
        The rhs target (src, dst, edge)
    lhs_data : Tensor
        The lhs data
    rhs_data : Tensor
        The rhs data
    out_size : int
        Size of first dimension of output data
    lhs_map : tuple
        Two lhs id mapping arrays, one for forward pass, the other for backward
    rhs_map : tuple
        Two rhs id mapping arrays, one for forward pass, the other for backward
    out_map : tuple
        Two out id mapping arrays, one for forward pass, the other for backward

    Returns
    -------
    Tensor
        The result.
    """
    pass


def customdata_skin_clear():
    """Clear vertex skin layer

    """
    pass


def mass_tau(df):
    """
    Returns a calculated meteor mass as derived from using a constant luminous efficiency and the error in this value.

    :param df: dataframe containing all processed DAF data
    :return:
    """
    tau = 0.007
    intg_luminosity = 10 ** (-0.39026606 * df['avg_abs_mag'] + 1.96769668
        ) * 2.5
    mass = 2.0 / (tau * df['vel_avg'] ** 2) * intg_luminosity
    mass_err = abs(4 * tau ** -1 * df['vel_avg'] ** -3 * intg_luminosity
        ) + abs(2 * tau ** -1 * df['vel_avg'] ** -2 * df['intg_luminosity_err']
        )
    return mass, mass_err


def in_hm2(var):
    """
    Return whether the variant was part of HapMap2
    """
    return var.INFO.get('H2')


def _create_valid_graph(graph):
    """Sets all weights of edges for different edges as 1, inplace.

    Parameters
    ----------
    graph : :class:`~gensim.summarization.graph.Graph`
        Given graph.

    """
    nodes = graph.nodes()
    for i in range(len(nodes)):
        for j in range(len(nodes)):
            if i == j:
                continue
            edge = nodes[i], nodes[j]
            if graph.has_edge(edge):
                graph.del_edge(edge)
            graph.add_edge(edge, 1)


@staticmethod
def get_preface_latex():
    """
        Returns preface code of Latex document.

        Returns
        -------
        str
        """
    preface = '\\documentclass[12pt]{article}\n'
    preface += '\\usepackage{Qcircuit_v2, Qcircuit_extension}\n'
    preface += '\\begin{document}\n'
    preface += '\n\n'
    return preface


def ingredients(amount: int=1) ->None:
    """
    Prints out the ingredients needed to make batch(es) of pancakes!

    See https://stackoverflow.com/questions/18275023/dont-show-long-options-twice-in-print-help-from-argparse
    for other information on argparse that shows more details on how to work with argparse.
    """
    print(f'{amount} cup of flour')
    print(f'{amount} pinch of salt')
    print(f'± {amount} cup of water')
    print(f'{amount} egg')
    print(f'{amount} teaspoon of baking powder')
    print(f'± {amount} cup of milk')
    print(f'\nMix ingredients together well')
    print(f'Texture of a thin bechamel')
    print(f'\nPour 1 ladle of mixture into a medium-hot pancake pan')
    print(f'Tilt pan to distribute a thin layer evenly over the surface')
    print(f'Turn after 1 minute')


def replace(uri, data, mimetype=None, filename=None):
    """ replace existing blob """


@classmethod
def linspace(cls, start, stop, num=50, endpoint=True):
    """Return evenly spaced numbers over a specified interval."""
    raise NotImplementedError


@classmethod
def from_payload(cls, payload):
    """
        Create NamedUser object based on results from a NamedUserList iterator.
        :param payload: Payload used to create the NamedUser object

        """
    for key in payload:
        setattr(cls, key, payload[key])
    return cls


def truncate_float(number, precision, round=False):
    """ Truncate (shorten) a floating point value at given precision """
    precision = abs(precision)
    if round:
        short_float = round(number, precision)
        """short_float = float("{0:.{1}f}".format(number, precision))
        """
    else:
        operate_on = 1
        for _ in range(precision):
            operate_on *= 10
        short_float = float(int(number * operate_on)) / operate_on
    return short_float


def str_to_num(i, exact_match=True):
    """
    Attempts to convert a str to either an int or float
    """
    if not isinstance(i, str):
        return i
    try:
        if not exact_match:
            return int(i)
        elif str(int(i)) == i:
            return int(i)
        elif str(float(i)) == i:
            return float(i)
        else:
            pass
    except ValueError:
        pass
    return i


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

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

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

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

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

    Returns
    -------
    out : NDArray or list of NDArrays
        The output of this function.

    Example
    -------

    >>> x = mx.nd.array([1, 2, 3, 4])
    >>> y = mx.nd.array([1.1, 2.1, 3.1, 4.1])
    >>> mx.nd.elemwise_add(x, y).asnumpy()
    array([ 2.0999999 ,  4.0999999 ,  6.0999999 ,  8.10000038], dtype=float32)
    """
    return 0,


def setRegisterNumbersForTemporaries(ast, start):
    """Assign register numbers for temporary registers, keeping track of
    aliases and handling immediate operands.
    """
    seen = 0
    signature = ''
    aliases = []
    for node in ast.postorderWalk():
        if node.astType == 'alias':
            aliases.append(node)
            node = node.value
        if node.reg.immediate:
            node.reg.n = node.value
            continue
        reg = node.reg
        if reg.n is None:
            reg.n = start + seen
            seen += 1
            signature += reg.node.typecode()
    for node in aliases:
        node.reg = node.value.reg
    return start + seen, signature


def safe_decode(txt):
    """Return decoded text if it's not already bytes."""
    try:
        return txt.decode()
    except AttributeError:
        return txt


@classmethod
def init(cls, *args, **kwargs):
    """Initialize the config like as you would a regular dict."""
    instance = cls()
    instance._values.update(dict(*args, **kwargs))
    return instance


def get_parser():
    """Build parser object"""
    from argparse import ArgumentParser
    from argparse import RawTextHelpFormatter
    parser = ArgumentParser(description=
        "OpenfMRI participants sampler, for FMRIPREP's testing purposes",
        formatter_class=RawTextHelpFormatter)
    parser.add_argument('openfmri_dir', action='store', help=
        'the root folder of a the openfmri dataset')
    parser.add_argument('output_dir', action='store', help=
        'the directory where outputs should be stored')
    parser.add_argument('sample_file', action='store', help=
        'a YAML file containing the subsample schedule')
    parser.add_argument('--anat-only', action='store_true', default=False,
        help='run only anatomical workflow')
    parser.add_argument('--nthreads', action='store', type=int, help=
        'number of total threads')
    parser.add_argument('--omp_nthreads', action='store', type=int, help=
        'number of threads for OMP-based interfaces')
    parser.add_argument('--mem-gb', action='store', type=int, help=
        'available memory in GB')
    parser.add_argument('--tasks-list-file', default='tasks_list.sh',
        action='store', help='write output file')
    parser.add_argument('-t', '--tasks-filter', action='store', nargs='*',
        help='run only specific tasks')
    parser.add_argument('--cmd-call', action='store', help='command to be run')
    return parser


def positions_threshold_tag_from_positions_threshold(positions_threshold):
    """Generate a positions threshold tag, to customize phase names based on the threshold that positions are required     to trace within one another.

    This changes the phase name 'phase_name' as follows:

    positions_threshold = 1 -> phase_name
    positions_threshold = 2 -> phase_name_positions_threshold_2
    positions_threshold = 2 -> phase_name_positions_threshold_2
    """
    if positions_threshold is None:
        return ''
    return '__pos_{0:.2f}'.format(positions_threshold)


@classmethod
def bin_by_custom(cls, starts, stops):
    """
        Simplicity function to make custom bins. This form keeps introduction of
        custom bins uniform for other binning methods

        :param start: start times of the bins
        :param stop:  stop times of the bins
        :return:
        """
    return cls.from_starts_and_stops(starts, stops)


def state_del():
    """Delete current boid state

    """
    pass


def try_convert_float(float_value):
    """
    Try convert object to a float.

    Args:
        Float_value: value of string, float or integer
    Returns:
        Tuple of float and boolean. boolean indicates if value was converted.
    """
    if isinstance(float_value, (float, int)):
        return float_value, True
    try:
        float_value = float(float_value.replace(',', '.'))
        return float_value, True
    except ValueError:
        return 0.0, False
    except:
        print('Error converting {} to float'.format(float_value))
        return 0.0, False


def copula_bv_indep(u, v):
    """independent bivariate copula
    """
    return u * v


def provides(varmap):
    """Return a minimal ``provides`` list from the setup vars.
    """
    try:
        return ['{} ({})'.format(varmap['name'], varmap['version'])]
    except KeyError:
        return [varmap['name']]


@classmethod
def get_max_blob_size(cls, field_name):
    """Get the maximum allowed blob size in bytes.

        :param field_name: blob or blob dict field name
        :return: maximum blob size in bytes
        """
    return getattr(cls.fields[field_name], 'max_blob_size')


def group_ungroup():
    """Ungroup selected nodes

    """
    pass


def create_application(factory, folder, name):
    """Create and add a new Grok application to the given folder under
        name.
        """


def _count_duplicated_locations(locations, new):
    """
    To calculate the count of duplicated locations for new one.

    :param locations: The exiting image location set
    :param new: The new image location
    :returns: The count of duplicated locations
    """
    ret = 0
    for loc in locations:
        if loc['url'] == new['url'] and loc['metadata'] == new['metadata']:
            ret += 1
    return ret


def instance_id(instance):
    """
    Return id of instance in hex form.
    Helps in logs/debugs/development troubleshooting.
    """
    instance_id = hex(id(instance))[2:]
    return instance_id


def get_user_quota(user):
    """
    Tiny helper for getting quota dict for user (left mostly for backward compatibility)
    """
    return user.userplan.plan.get_quota_dict()


@classmethod
def tags_line(cls, name, tagmap):
    """ Transcribe a `name` and its `tagmap` for use as a `.fstags` file line.
    """
    fields = [cls.encode_name(name)]
    for tag in tagmap:
        fields.append(str(tag))
    return ' '.join(fields)


def reindent_lines(new_leader, source):
    """Re-indent string lines."""
    return new_leader + ('\n' + new_leader).join(source.split('\n'))


def int_to_bcd(integer):
    """Converts a two-digit, non-negative integer (0-99) to a one-byte
    binary coded decimal.

    :param: the integer value as a Python `int`.
    :returns: the 1-byte binary-coded decimal as a Python `int`.
    """
    assert 0 <= integer and integer <= 99
    ones = integer % 10
    tens = integer // 10
    return tens << 4 | ones


def _ensure_groups(handle, path):
    """
    Makes sure a path exists, returning the final group object.

    Parameters
    ----------
    handle : h5py.File
        The file handle in which to ensure the group.
    path : str
        The group to ensure inside the file.

    Examples
    --------
    >>> with h5py.File(temp_h5, 'w') as f:
    ...     _ensure_groups(f, '/potato')
    ...     '/potato' in f
    <HDF5 group "/potato" (0 members)>
    True
    """
    group = handle['/']
    heirarchy = path[1:].split('/')
    for name in heirarchy:
        if not name:
            continue
        elif name in group:
            group = group[name]
        else:
            group = group.create_group(name)
    return group


def noft(identifier: str, etype: str) ->TypeError:
    """Create and return a TypeError with preset 'not of type' error message.

    Args:
        identifier (str): Identifier name which does not have the correct type.
        etype (str): Expected class as string for the object named by the identifier.

    Returns:
        TypeError: Error with preset 'not of type' error message.
    """
    return TypeError(f'Given {identifier} is not of type {etype}.')


@staticmethod
def _regr_test():
    """
>>> import tempfile, os, shutil, pandas, random
>>> from oxtie.fronts import nums
>>> from oxtie.backs import simple
>>> random.seed(123)  # Make tests repeatable
>>> backend = simple.FileBackend(root=tempfile.mkdtemp(suffix='.oxtie'))
>>> idx = [pandas.Timestamp(
...     '2017-01-%s' % str(i).zfill(2)) for i in range(1,15)]
>>> estimate = [random.gauss(0, 1) for i in idx]
>>> reported = [e + .05 * random.gauss(0, 1) for e in estimate]
>>> p = pandas.DataFrame({'estimate': estimate, 'reported': reported},
...     index=idx)
>>> f = nums.SimpleFrame({'name': 'test'}, backend, frame=p)
>>> f.more = '*' * 10  # Add some more data in a property to save.
>>> f.save()
>>> g = backend.load({'name': 'test'}, allow_load=True)
>>> all(g.frame == f.frame) and f.more == g.more
True
>>> shutil.rmtree(backend.root)
"""


def swap_apico_basal(organo):
    """Swap apical and basal segments of an organoid
    """
    for elem in ['vert', 'face', 'edge']:
        swaped = organo.datasets[elem]['segment'].copy()
        swaped.loc[organo.segment_index('apical', elem)] = 'basal'
        swaped.loc[organo.segment_index('basal', elem)] = 'apical'
        organo.datasets[elem]['segment'] = swaped


def second_level(keys):
    """Return a dictionary with the nested keys, e.g. returns {'I':['a', 'b']} when keys=['I.a', 'I.b']"""
    sub_keys = {}
    for key in keys:
        if '.' in key:
            left, right = key.split('.', 1)
            sub_keys.setdefault(left, []).append(right)
    return sub_keys


def _extract_braces_expression(line, starting_braces_re, open_braces_re,
    closing_braces_re):
    """
    This function is taken from Plim package: https://pypi.python.org/pypi/Plim/

    :param line: may be empty
    :type line: str
    :param starting_braces_re:
    :param open_braces_re:
    :param closing_braces_re:
    """
    match = starting_braces_re.match(line)
    if not match:
        return None
    open_brace = match.group('start_brace')
    buf = [open_brace]
    tail = line[len(open_brace):]
    braces_counter = 1
    while tail:
        current_char = tail[0]
        if closing_braces_re.match(current_char):
            braces_counter -= 1
            buf.append(current_char)
            if braces_counter:
                tail = tail[1:]
                continue
            return u''.join(buf), tail[1:]
        if open_braces_re.match(current_char):
            braces_counter += 1
            buf.append(current_char)
            tail = tail[1:]
            continue
        buf.append(current_char)
        tail = tail[1:]
    raise Exception('Unexpected end of a route definition: {}'.format(line))


def __init__(context, tabview, request):
    """The multi-adapter adapts (context, tabview, request).
        """


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

        :param LookupError val:
        :rtype: ListRevisionsError
        """
    return cls('path', val)


def int_to_bytes(value):
    """Converts an integer to a big-endian sequence of bytes"""
    return value.to_bytes((value.bit_length() + 7) // 8, 'big')


def merge_headers(event):
    """
    Merge the values of headers and multiValueHeaders into a single dict.
    Opens up support for multivalue headers via API Gateway and ALB.
    See: https://github.com/Miserlou/Zappa/pull/1756
    """
    headers = event.get('headers') or {}
    multi_headers = (event.get('multiValueHeaders') or {}).copy()
    for h in set(headers.keys()):
        if h not in multi_headers:
            multi_headers[h] = [headers[h]]
    for h in multi_headers.keys():
        multi_headers[h] = ', '.join(multi_headers[h])
    return multi_headers


def p_rel_location_path_2(p):
    """RelativeLocationPath : RelativeLocationPath SLASH Step"""
    p[0] = list(p[1])
    p[0].append(p[3])


def Nu_vertical_helical_coil_Ali(Pr, Gr):
    """Calculates Nusselt number for natural convection around a vertical
    helical coil inside a tank or other vessel according to the Ali [1]_
    correlation.

    .. math::
        Nu_L = 0.555Gr_L^{0.301} Pr^{0.314}

    Parameters
    ----------
    Pr : float
        Prandtl number of the fluid surrounding the coil with properties
        evaluated at bulk conditions or as described in the notes [-]
    Gr : float
        Prandtl number of the fluid surrounding the coil with properties
        evaluated at bulk conditions or as described in the notes
        (for the two temperatures, use the average coil fluid temperature and
        the temperature of the fluid outside the coil) [-]

    Returns
    -------
    Nu : float
        Nusselt number with respect to the total length of the helical coil
        (and bulk thermal conductivity), [-]

    Notes
    -----
    In [1]_, the temperature at which the fluid surrounding the coil's
    properties were evaluated at was calculated in an unusual fashion. The
    average temperature of the fluid inside the coil
    :math:`(T_{in} + T_{out})/2` is averaged with the fluid outside the coil's
    temperature.

    The correlation is valid for Prandtl numbers between 4.4 and 345,
    and tank diameter/coil outer diameter ratios between 10 and 30.

    Examples
    --------
    >>> Nu_vertical_helical_coil_Ali(4.4, 1E11)
    1808.5774997297106

    References
    ----------
    .. [1] Ali, Mohamed E. "Natural Convection Heat Transfer from Vertical
       Helical Coils in Oil." Heat Transfer Engineering 27, no. 3 (April 1,
       2006): 79-85.
    """
    return 0.555 * Gr ** 0.301 * Pr ** 0.314


def isSameLocusFamily(gene1, gene2, scoresO, genesO, paramD, synThresholdD):
    """Given two genes in the same family, determine if they meet the
synteny requirements to be put in the same LocusFamily. Returns
boolean.
    """
    if not scoresO.isEdgePresentByEndNodes(gene1, gene2):
        return False
    coreSynSc = scoresO.getScoreByEndNodes(gene1, gene2, 'coreSynSc')
    synSc = scoresO.getScoreByEndNodes(gene1, gene2, 'synSc')
    strain1 = genesO.numToStrainName(gene1)
    strain2 = genesO.numToStrainName(gene2)
    strainPair = tuple(sorted([strain1, strain2]))
    minSynThreshold = synThresholdD['minSynThreshold'][strainPair]
    minCoreSynThreshold = synThresholdD['minCoreSynThreshold'][strainPair]
    if coreSynSc < minCoreSynThreshold or synSc < minSynThreshold:
        addIt = False
    else:
        addIt = True
    return addIt


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

        :param SharedLinkSettingsAddPasswordType val:
        :rtype: EventType
        """
    return cls('shared_link_settings_add_password', val)


def guess_type(value: str):
    """
    Converts value in int or float if possible
    """
    try:
        return int(value)
    except ValueError:
        pass
    try:
        return float(value)
    except ValueError:
        pass
    return value


def overlap(start1, end1, start2, end2, tolerance=0):
    """Check that range (start1, end1) overlaps with (start2, end2)."""
    return end1 + tolerance >= start2 and end2 + tolerance >= start1


def num_ascents(perm):
    """Returns the number of ascents of the permutation

    >>> Permutation(42561873).num_ascents()
    3
    """
    return len(perm.ascent_set())


@staticmethod
def col_width(df, column, as_value=False) ->tuple:
    """ gets the max and min length or values of a column as a (max, min) tuple

        :param df: the pandas.DataFrame
        :param column: the column to find the max and min for
        :param as_value: if the return should be a length or the values. Default is False
        :return: returns a tuple with the (max, min) length or values
        """
    if as_value:
        field_length = df[column].apply(str).str.len()
        return df.loc[field_length.argmax(), column], df.loc[field_length.
            argmin(), column]
    return df[column].apply(str).str.len().max(), df[column].apply(str
        ).str.len().min()


def copy():
    """ Makes a copy of the response and returns the copy. """


def __call__(term):
    """ Returns a list of value, title tuples matching the given term
        """


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_keywords():
    """Get the keywords needed to look up the version information."""
    git_refnames = '$Format:%d$'
    git_full = '$Format:%H$'
    git_date = '$Format:%ci$'
    keywords = {'refnames': git_refnames, 'full': git_full, 'date': git_date}
    return keywords


def format_time(seconds):
    """
    Format time in secods into human readable string
    Args:
        seconds: time in seconds
    Returns:
        The time formatted
    """
    mins, secs = divmod(seconds, 60)
    return '{}:{:02d}'.format(int(mins), round(secs))


def get_process_identifier(args):
    """by looking at arguments we try to generate a proper identifier
        >>> get_process_identifier(['python', 'echo.py', '1'])
        'python_echo.py_1'
    """
    return '_'.join(args)


def requestSubmitted(request):
    """A new BuildRequest has been submitted to the buildmaster.

        @type request: implementer of L{IBuildRequestStatus}
        """


def transpose(a, axes=None):
    """Permute the dimensions of an array.

    :arg a: :class:`GPUArray`
    :arg axes: list of ints, optional.
        By default, reverse the dimensions, otherwise permute the axes
        according to the values given.

    :returns: :class:`GPUArray` A view of the array with its axes permuted.

    .. versionadded:: 2015.2
    """
    return a.transpose(axes)


def is_notebook():
    """ Jupyter Notebook을 사용하는지 확인하는 함수

    Returns
    -------
    bool
        Jupyter Notebook 사용시 True
    """
    try:
        from IPython import get_ipython
        if 'IPKernelApp' not in get_ipython().config:
            return False
    except Exception:
        return False
    return True


def _set_sql_mode(sql_mode, dbapi_con, connection_rec):
    """Set the sql_mode session variable.

    MySQL supports several server modes. The default is None, but sessions
    may choose to enable server modes like TRADITIONAL, ANSI,
    several STRICT_* modes and others.

    Note: passing in '' (empty string) for sql_mode clears
    the SQL mode for the session, overriding a potentially set
    server default.
    """
    cursor = dbapi_con.cursor()
    cursor.execute('SET SESSION sql_mode = %s', [sql_mode])


def path_string_is_slash_end(path_string, delimiter='/'):
    """
        from xdict.utils import *
        path_string_is_slash_end('a/b/c')
        path_string_is_slash_end('a/b/c/')
        path_string_is_slash_end('a#b#c#',delimiter='#')
    """
    if path_string == '':
        return False
    if path_string[-1] == delimiter:
        return True
    else:
        return False


def time_series_split(X, test_size=0.2, number=False, output_numpy=True):
    """
    Splits a dataset according to the time the data was taken
    :param X:
    :param test_size:
    :param output_numpy:
    :return:
    """
    if test_size <= 1 and not number:
        ntrn = int(len(X) * (1 - test_size))
    elif test_size > 1 and number:
        ntrn = int(len(X) - test_size)
    else:
        raise ValueError(
            'test_size: (frac or Int) and number:(True or False) should be set correctly'
            )
    X_train = X[0:ntrn]
    X_test = X[ntrn:]
    return X_train, X_test


def load_twisted_conch_ssh_transport(finder, module):
    """the twisted.conch.ssh.transport module uses __import__ builtin to
       dynamically load different ciphers at runtime."""
    finder.IncludePackage('Crypto.Cipher')


def operator_check(*args):
    """
    assertions for inputs passed to operator-type blocks
    """
    pass


def discard(queue):
    """
    Policy for discarding the current element
    when the queue is full.
    @param queue: Queue that has reached size limit
    @return: 1 to discontinue processing
    """
    return 1


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

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

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

        Example::

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

        @rtype: C{dict}.
        """


def mirror_mag_d(distance_image, distance_object):
    """Usage: Find magnification using distance of image and distance of object"""
    neg_di = -1 * distance_image
    return neg_di / distance_object


def _check_elm_dataframe(df):
    """Check DataFrame Format.

    Parameters
    ----------

    Returns
    -------

    """
    if 'Regex' in df.columns and df.shape[0] > 0:
        return True
    else:
        return False


@classmethod
def create_attributes(klass, attributes, previous_object=None):
    """
        Attributes for environment creation.
        """
    return {'name': attributes.get('name', None)}


@classmethod
def delete_port_forwarding(cls, pf, client=None):
    """Delete port forwarding

        :param client: Client to be used
        If client is not given it will use the client used to create
        the port forwarding, or cls.client if unknown.
        """
    client = client or pf.get('client') or cls.client
    client.delete_port_forwarding(pf['floatingip_id'], pf['id'])


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 find_lowest_point(slab):
    """
    This function is able to find the lowest point of the slab, it is used in slab_generator function.

    Parameters:

    Slab:
        ASE Atoms Object. The slab that we want.

    Return:
        A real number. Return the lowest point in the slab
    """
    lowest_height = 100000
    for atom in slab:
        if atom.position[2] < lowest_height:
            lowest_height = atom.position[2]
    return lowest_height


def strlize(l):
    """
        from elist.elist import *
        l = [1,3,4,5]
        strlize(l)
    """
    return list(map(lambda ele: str(ele), l))


def xmlstub(model, example=False):
    """
    Write the model data to a XML file wrapped with a root element and
    namespace declarations.
    """
    print('Writing data instance for ', model, ' to stub.xml')
    with open('stub.xml', 'w') as f:
        f.write(
            """<?xml version='1.0' encoding='UTF-8'?>
    <s3m:root xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:s3m="https://www.s3model.com/ns/s3m/"
      targetNamespace="https://www.s3model.com/ns/s3m/"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation='https://www.s3model.com/ns/s3m/ stub.xsd'
    >

    """
            )
        f.write(model.getXMLInstance(example))
        f.write('</s3m:root>\n')


def get(project, version=None):
    """Return a tuple (version, file) with the the egg for the specified
        project and version. If version is None, the latest version is
        returned. If no egg is found for the given project/version (None, None)
        should be returned."""


@staticmethod
def edit_distance(s, t):
    """ Also known as Levenshtein distance
            From Wikipedia article; Iterative with two matrix rows """
    if s == t:
        return 0
    elif len(s) == 0:
        return len(t)
    elif len(t) == 0:
        return len(s)
    v0 = [None] * (len(t) + 1)
    v1 = [None] * (len(t) + 1)
    for i in range(len(v0)):
        v0[i] = i
    for i in range(len(s)):
        v1[0] = i + 1
        for j in range(len(t)):
            cost = 0 if s[i] == t[j] else 1
            v1[j + 1] = min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost)
        for j in range(len(v0)):
            v0[j] = v1[j]
    return v1[len(t)]


def to_return_index(dataframe, ticker_col='RIC_CD', date_col='MARKETDATE'):
    """
    Transform TRQA Return Index into EQI Factor format.
    :param dataframe: TRQA Return Index dataframe
    :param ticker_col: ticker column name
    :param date_col: date column name
    :return: TRQA Return Index in EQI Factor format
    """
    return dataframe.to_eqi().e_rename({ticker_col: 'asset', date_col: 'Date'}
        ).e_select('Date', 'asset', 'RI').e_set_index('Date', 'asset'
        ).e_groupby('asset').e_apply(lambda df: df.to_eqi().e_groupby(
        'Date').sum().to_pandas()).unstack(0).e_drop_level(0).resample('d'
        ).bfill().sort_index().to_pandas()


@classmethod
def _connexion_to_framework_response(cls, response, mimetype, extra_context
    =None):
    """ Cast ConnexionResponse to framework response class """
    return cls._build_response(mimetype=response.mimetype or mimetype,
        status_code=response.status_code, content_type=response.
        content_type, headers=response.headers, data=response.body,
        extra_context=extra_context)


def lazy_isinstance(instance, module, name):
    """Use string representation to identify a type."""
    module = type(instance).__module__ == module
    name = type(instance).__name__ == name
    return module and name


def process_tracked_yield(minIONdict):
    """
    This function maintains a history of all yield values over the time of a run - it can be configured to store yields
    at given intervals. It is used by the main web page to provide a history of cumulative yield.
    """
    for minion in minIONdict:
        if 'detailsdata' in minIONdict[minion]:
            if 'livedata' in minIONdict[minion]:
                if 'yield_res' in minIONdict[minion]['livedata']:
                    if 'result' in minIONdict[minion]['livedata']['yield_res']:
                        try:
                            asictemp = float(minIONdict[minion][
                                'detailsdata']['engine_states'][
                                'minion_asic_temperature'])
                        except:
                            asictemp = 0
                        try:
                            heatsinktemp = float(minIONdict[minion][
                                'detailsdata']['engine_states'][
                                'minion_heatsink_temperature'])
                        except:
                            heatsinktemp = 0
                        if minIONdict[minion]['livedata']['bias_voltage_gain'][
                            'result'] != 'null':
                            biasvoltage = int(minIONdict[minion]['livedata'
                                ]['bias_voltage_gain']['result'])
                        else:
                            biasvoltage = 0
                        if minIONdict[minion]['livedata']['biasvoltageget'][
                            'result'] != 'null':
                            voltage_val = int(minIONdict[minion]['livedata'
                                ]['biasvoltageget']['result']['bias_voltage'])
                        else:
                            voltage_val = 0
                        voltage_value = voltage_val * biasvoltage
                        try:
                            if minIONdict[minion]['livedata']['yield_res'][
                                'result'] != 'null':
                                yieldval = int(minIONdict[minion][
                                    'livedata']['yield_res']['result'])
                            else:
                                yieldval = minIONdict[minion]['detailsdata'][
                                    'statistics']['read_event_count']
                        except:
                            yieldval = 0
                        try:
                            meanratio = minIONdict[minion]['detailsdata'][
                                'meanratio']
                            openpore = minIONdict[minion]['detailsdata'][
                                'openpore']
                            instrand = minIONdict[minion]['detailsdata'][
                                'instrand']
                        except:
                            meanratio = 0
                            openpore = 0
                            instrand = 0
                        if 'yield_history' not in minIONdict[minion]:
                            minIONdict[minion]['yield_history'] = []
                        if 'temp_history' not in minIONdict[minion]:
                            minIONdict[minion]['temp_history'] = dict()
                        if 'pore_history' not in minIONdict[minion]:
                            minIONdict[minion]['pore_history'] = dict()
                        if 'meanratio_history' not in minIONdict[minion][
                            'pore_history']:
                            minIONdict[minion]['pore_history'][
                                'meanratio_history'] = []
                            minIONdict[minion]['pore_history'][
                                'openpore_history'] = []
                            minIONdict[minion]['pore_history'][
                                'instrand_history'] = []
                        if 'strand' not in minIONdict[minion]['pore_history']:
                            minIONdict[minion]['pore_history']['strand'] = []
                            minIONdict[minion]['pore_history']['percent'] = []
                            minIONdict[minion]['pore_history']['single'] = []
                        if 'asictemp' not in minIONdict[minion]['temp_history'
                            ]:
                            minIONdict[minion]['temp_history']['asictemp'] = []
                            minIONdict[minion]['temp_history']['heatsinktemp'
                                ] = []
                            minIONdict[minion]['temp_history']['voltage'] = []
                        strand = 0
                        single_pore = 0
                        if 'simplesummary' in minIONdict[minion]:
                            if 'strand' in minIONdict[minion]['simplesummary'
                                ].keys():
                                strand = float(minIONdict[minion][
                                    'simplesummary']['strand'])
                            if 'single_pore' in minIONdict[minion][
                                'simplesummary'].keys():
                                single_pore = float(minIONdict[minion][
                                    'simplesummary']['single_pore'])
                            elif 'good_single' in minIONdict[minion][
                                'simplesummary'].keys():
                                single_pore = float(minIONdict[minion][
                                    'simplesummary']['good_single'])
                        if strand + single_pore > 0:
                            percent = strand / (strand + single_pore) * 100
                        else:
                            percent = 0
                        if len(minIONdict[minion]['yield_history']) > 1:
                            if yieldval > minIONdict[minion]['yield_history'][
                                -1][1]:
                                minIONdict[minion]['yield_history'].append((
                                    minIONdict[minion]['detailsdata'][
                                    'timestamp'] * 1000, yieldval))
                            minIONdict[minion]['temp_history']['asictemp'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, asictemp))
                            minIONdict[minion]['temp_history']['voltage'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, voltage_value))
                            minIONdict[minion]['temp_history']['heatsinktemp'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, heatsinktemp))
                            minIONdict[minion]['pore_history']['strand'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, strand))
                            minIONdict[minion]['pore_history']['percent'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, percent))
                            minIONdict[minion]['pore_history']['single'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, single_pore))
                            minIONdict[minion]['pore_history'][
                                'meanratio_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                meanratio))
                            minIONdict[minion]['pore_history'][
                                'openpore_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                openpore))
                            minIONdict[minion]['pore_history'][
                                'instrand_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                instrand))
                            if 'simplesummary' in minIONdict[minion]:
                                if 'details' not in minIONdict[minion][
                                    'pore_history'].keys():
                                    minIONdict[minion]['pore_history'][
                                        'details'] = dict()
                                for state in minIONdict[minion]['simplesummary'
                                    ].keys():
                                    if state not in minIONdict[minion][
                                        'pore_history']['details'].keys():
                                        minIONdict[minion]['pore_history'][
                                            'details'][state] = []
                                    minIONdict[minion]['pore_history'][
                                        'details'][state].append((
                                        minIONdict[minion]['detailsdata'][
                                        'timestamp'] * 1000, minIONdict[
                                        minion]['simplesummary'][state]))
                        else:
                            minIONdict[minion]['yield_history'].append((
                                minIONdict[minion]['detailsdata'][
                                'timestamp'] * 1000, yieldval))
                            minIONdict[minion]['temp_history']['asictemp'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, asictemp))
                            minIONdict[minion]['temp_history']['heatsinktemp'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, heatsinktemp))
                            minIONdict[minion]['temp_history']['voltage'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, voltage_value))
                            minIONdict[minion]['pore_history']['strand'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, strand))
                            minIONdict[minion]['pore_history']['percent'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, percent))
                            minIONdict[minion]['pore_history']['single'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, single_pore))
                            minIONdict[minion]['pore_history'][
                                'meanratio_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                meanratio))
                            minIONdict[minion]['pore_history'][
                                'openpore_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                openpore))
                            minIONdict[minion]['pore_history'][
                                'instrand_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                instrand))
                            if 'simplesummary' in minIONdict[minion]:
                                if 'details' not in minIONdict[minion][
                                    'pore_history'].keys():
                                    minIONdict[minion]['pore_history'][
                                        'details'] = dict()
                                for state in minIONdict[minion]['simplesummary'
                                    ].keys():
                                    if state not in minIONdict[minion][
                                        'pore_history']['details'].keys():
                                        minIONdict[minion]['pore_history'][
                                            'details'][state] = []
                                    minIONdict[minion]['pore_history'][
                                        'details'][state].append((
                                        minIONdict[minion]['detailsdata'][
                                        'timestamp'] * 1000, minIONdict[
                                        minion]['simplesummary'][state]))
                else:
                    minIONdict[minion]['yield_history'] = []
                    minIONdict[minion]['temp_history']['asictemp'] = []
                    minIONdict[minion]['temp_history']['heatsinktemp'] = []
                    minIONdict[minion]['temp_history']['voltage'] = []
                    minIONdict[minion]['pore_history']['strand'] = []
                    minIONdict[minion]['pore_history']['percent'] = []
                    minIONdict[minion]['pore_history']['single'] = []
                    minIONdict[minion]['pore_history']['openpore_history'] = []
                    minIONdict[minion]['pore_history']['instrand_history'] = []
                    minIONdict[minion]['pore_history']['meanratio_history'] = [
                        ]
                    if 'details' in minIONdict[minion]['pore_history']:
                        minIONdict[minion]['pore_history'].pop('details')


@classmethod
def disable(cls, user_id, github_id, name):
    """Disable webhooks for a repository.

        Disables the webhook from a repository if it exists in the DB.

        :param user_id: User identifier.
        :param repo_id: GitHub id of the repository.
        :param name: Fully qualified name of the repository.
        """
    repo = cls.get(user_id, github_id=github_id, name=name)
    repo.hook = None
    repo.user_id = None
    return repo


@staticmethod
def clenshaw(x, coeffs):
    """Evaluates the polynomial using Clenshaw's algorithm."""
    if len(coeffs) == 1:
        c0 = coeffs[0]
        c1 = 0
    elif len(coeffs) == 2:
        c0 = coeffs[0]
        c1 = coeffs[1]
    else:
        x2 = 2 * x
        c0 = coeffs[-2]
        c1 = coeffs[-1]
        for i in range(3, len(coeffs) + 1):
            tmp = c0
            c0 = coeffs[-i] - c1
            c1 = tmp + c1 * x2
    return c0 + c1 * x


def gl_get_alignment(width):
    """Determines a textures byte alignment.

    If the width isn't a power of 2
    we need to adjust the byte alignment of the image.
    The image height is unimportant

    www.opengl.org/wiki/Common_Mistakes#Texture_upload_and_pixel_reads
    """
    alignments = [4, 8, 2, 1]
    for alignment in alignments:
        if width % alignment == 0:
            return alignment


def import_moderator(app):
    """
    Import moderator module and register all models it contains with moderation
    """
    from importlib import import_module
    import imp
    try:
        app_path = import_module(app).__path__
    except AttributeError:
        return None
    try:
        imp.find_module('moderator', app_path)
    except ImportError:
        return None
    module = import_module('%s.moderator' % app)
    return module


def ipm(occurrences, N):
    """Relative frequency of `occurrences` in corpus, in instances per million.

    """
    return 1000000.0 * len(occurrences) / N


def cms_groups():
    """Return list of CMS data-ops groups"""
    groups = ['DATAOPS']
    return groups


def func_namespace(func, deco_args):
    """Generates a unique namespace for a function"""
    kls = None
    if hasattr(func, 'im_func'):
        kls = func.im_class
        func = func.im_func
    deco_key = ' '.join(map(str, deco_args))
    if kls:
        return '%s.%s.%s' % (kls.__module__, kls.__name__, deco_key)
    else:
        return '%s.%s.%s' % (func.__module__, func.__name__, deco_key)


def _value_to_boolean(value):
    """Converts true-ish and false-ish values to boolean."""
    try:
        value = value.upper()
        if value in ['TRUE', 'T']:
            return True
        elif value in ['FALSE', 'F']:
            return False
    except AttributeError:
        pass
    try:
        value = int(value)
        return True if value == 1 else False
    except (TypeError, ValueError):
        pass
    raise ValueError('Cannot convert value {0} to boolean.'.format(value))


def dottedQuadToNum(ip):
    """
    Convert decimal dotted quad string to long integer

    >>> int(dottedQuadToNum('1 '))
    1
    >>> int(dottedQuadToNum(' 1.2'))
    16777218
    >>> int(dottedQuadToNum(' 1.2.3 '))
    16908291
    >>> int(dottedQuadToNum('1.2.3.4'))
    16909060
    >>> dottedQuadToNum('255.255.255.255')
    4294967295
    >>> dottedQuadToNum('255.255.255.256')
    Traceback (most recent call last):
    ValueError: Not a good dotted-quad IP: 255.255.255.256
    """
    import socket, struct
    try:
        return struct.unpack('!L', socket.inet_aton(ip.strip()))[0]
    except socket.error:
        raise ValueError('Not a good dotted-quad IP: %s' % ip)
    return


def key_to_alpha(key):
    """ Generate alphabet for key

    Idea is run through the key, dropping any
    letters already seen.

    Then go back to the beginning of the alphabet and
    write letters out that are not in the key.
    """
    alphabet = ''
    used = set()
    for c in key:
        if c.lower() not in used:
            alphabet += c
            used.add(c)
    a = ord('a')
    for xx in range(26):
        c = chr(a + xx)
        if c not in used:
            alphabet += c
    return alphabet


@staticmethod
def _fmt_opt(name):
    """'auto_root' -> '--auto-root'."""
    return '--' + name.replace('_', '-')


def _numlines(s):
    """Returns the number of lines in s, including ending empty lines."""
    return len((s + b'x').splitlines())


def add_columns(header, c):
    """
    add any missing columns to the samples table
    """
    for column in header:
        try:
            c.execute('ALTER TABLE samples ADD COLUMN {0}'.format(column))
        except:
            pass


def multiply_vector(vector, factor):
    """Multiplies a vector of two coordinates by a given factor."""
    return factor * vector[0], factor * vector[1]


def config(organization: str, project: str, pat: str):
    """Store configuration on file"""


@classmethod
def _latest_partition_from_df(cls, df):
    """Hive partitions look like ds={partition name}"""
    return df.ix[:, (0)].max().split('=')[1]


@classmethod
def commit(cls):
    """
        Call commit on the thread-local database transaction. "Begin" must be
        called to start a new transaction at this point, if a new transaction
        is desired.
        """
    if cls.app.local.sqla_tx is not None:
        cls.app.local.sqla_tx.commit()
        cls.app.local.sqla_tx = None


@staticmethod
def parse_id(url):
    """Parses the file name, extension and the preceding identifier from the url."""
    return '/'.join(url.rsplit('/', 2)[-2:])


@staticmethod
def batchify(tensor_data, batch_size, device):
    """
        将数据按batch_size分批
        :param tensor_data:
        :param batch_size:
        :param device:
        :return:
        """
    num_batch = tensor_data.size(0) // batch_size
    tensor_data = tensor_data.narrow(0, 0, num_batch * batch_size)
    tensor_data = tensor_data.view(batch_size, -1).t().contiguous()
    return tensor_data.to(device)


def datetime_tuple_to_long(year: int, month: int, day: int, hour: int,
    minute: int, second: int, msecond: int=0) ->int:
    """ self contained to avoid function calling overhead """
    mth: int = (month + 9) % 12
    yr: int = year - mth // 10
    date_int: int = 365 * yr + yr // 4 - yr // 100 + yr // 400 + (mth * 306 + 5
        ) // 10 + (day - 1)
    time_int: int = (hour * 3600 * 1000 + minute * 60 * 1000 + second *
        1000 + msecond // 1000)
    return (date_int << 32) + time_int


def getRegionMeasureNumbers(scoreIn, region='Page'):
    """
    get a list where each entry is a 2-tuplet whose first number
    refers to the first measure on a page and whose second number
    is the last measure on the page.
    """
    if region == 'Page':
        classesToReturn = ['PageLayout']
    elif region == 'System':
        classesToReturn = ['PageLayout', 'SystemLayout']
    else:
        raise ValueError('region must be one of Page or System')
    firstPart = scoreIn.parts[0]
    allMeasures = firstPart.getElementsByClass('Measure')
    firstMeasureNumber = allMeasures[0].number
    lastMeasureNumber = allMeasures[-1].number
    measureStartList = [firstMeasureNumber]
    measureEndList = []
    allAppropriateLayout = firstPart.flat.getElementsByClass(classesToReturn)
    for pl in allAppropriateLayout:
        plMeasureNumber = pl.measureNumber
        if pl.isNew is False:
            continue
        if plMeasureNumber not in measureStartList:
            measureStartList.append(plMeasureNumber)
            measureEndList.append(plMeasureNumber - 1)
    measureEndList.append(lastMeasureNumber)
    measureList = list(zip(measureStartList, measureEndList))
    return measureList


@classmethod
def generate_custom_tree(cls, dtc_args):
    """Generates a custom Decision Tree wrapper.
        :param dtc_args: parameters to pass into the decision tree
        :type dtc_args: dict
        :rtype: cls
        """
    return type('Custom' + cls.__name__, (cls,), {'_dtc_args': dtc_args})


def convert_to_valid_module_name(name):
    """Convert a module name to a PEP8 compliant module name.

    * lowercase
    * whitespace -> underscore
    * dash -> underscore
    * if leading numeric character, prepend '_'
      Names like this are discouraged by https://www.python.org/dev/peps/pep-0008/#package-and-module-names,
      but so are, names starting with a numeric character.
    """
    if name[0].isnumeric():
        name = '_' + name
    valid_module_name = name.lower().replace('-', '_').replace(' ', '_')
    return valid_module_name


def ssq_to_ind(ssq, sz):
    """
    Convert the value of :math:`S^{2}` for a given :math:`S_{z}` to an index.

    Parameters
    ----------
    ssq : int
        Value of :math:`S^{2}`.
    sz : int
        Value of :math:`S_{z}`.

    Returns
    -------
    int
        An index corresponding to given :math:`S^{2}` and :math:`S_{z}`.
    """
    return int((ssq - abs(sz)) / 2)


@staticmethod
def _committed_eclass(committed, eclass):
    """Stub method for matching eclasses against commits."""
    return eclass in committed


def repeat(chars: str, count: int) ->str:
    """Return a string of repeated characters.

    :param chars: The characters to repeat.
    :param count: The number of times to repeat.
    :return: The string of repeated characters.
    """
    return chars * count


def to_str(v):
    """convert *v* to `str`."""
    return v if isinstance(v, str) else v.decode('utf-8') if isinstance(v,
        bytes) else v.encode('utf-8')


def package_version_check(args, parser):
    """Check exclusive nature of --package-version argument
    """
    if (args.build or args.check) and args.package_version:
        parser.error('--package-version works only with --create')


def _sl_fit(estimator, X, y, pb, **fit_params):
    """Aux. function to fit SlidingEstimator in parallel.

    Fit a clone estimator to each slice of data.

    Parameters
    ----------
    base_estimator : object
        The base estimator to iteratively fit on a subset of the dataset.
    X : array, shape (n_samples, nd_features, n_estimators)
        The target data. The feature dimension can be multidimensional e.g.
        X.shape = (n_samples, n_features_1, n_features_2, n_estimators)
    y : array, shape (n_sample, )
        The target values.
    fit_params : dict | None
        Parameters to pass to the fit method of the estimator.

    Returns
    -------
    estimators_ : list of estimators
        The fitted estimators.
    """
    from sklearn.base import clone
    estimators_ = list()
    for ii in range(X.shape[-1]):
        est = clone(estimator)
        est.fit(X[..., ii], y, **fit_params)
        estimators_.append(est)
        pb.update(ii + 1)
    return estimators_


def get_arff(feat_path):
    """Do-nothing reader for ARFF format."""
    return feat_path


def is_subdir(subdir_path, dir_path):
    """Returns "True" if it's the second path parameter is a subdirectory of the first path parameter."""
    return (subdir_path.rstrip('/') + '/').startswith(dir_path.rstrip('/') +
        '/')


@staticmethod
def basit_seri(data):
    """
        Verilen veriyi küçükten büyüğe sıralar.
        :param data: Tek boyutlu bir liste.
        :returns: Verilen listenin küçükten büyüğe sıralanmış hali.
        """
    return sorted(data)


def _custom_arrows(sources, targets, angle):
    """
    Create a curved arrow between `source` and `target` as the combination of
    the arc of a circle and a triangle.

    The initial and final angle $lpha$ between the source-target line and
    the arrow is linked to the radius of the circle, $r$ and the distance $d$
    between the points:

    .. math:: r = rac{d}{2 \\cdot 	an(lpha)}

    The beginning and the end of the arc are given through initial and final
    angles, respectively $	heta_1$ and $	heta_2$, which are given with
    respect to the y-axis; This leads to $lpha = 0.5(	heta_1 - 	heta_2)$.
    """
    pass


def unpack_int(value):
    """Unpack the given string into an integer.

    :type value: string
    :param value: The string to unpack.

    :rtype: integer
    :returns: The string as an integer.
    """
    return int(value)


def create_base_url(host, use_ssl):
    """
    Concatenates host url with ssl use
    :return: (string) Base url
    """
    if use_ssl:
        return 'https://%s' % host
    return 'http://%s' % host


def getState():
    """ get the state of the queue, i.e. its contents """


@staticmethod
def _reformat_data(data):
    """Reformat map of entities to list of respective entry values.

        As Gerrit returns a map that maps entity names to respective entries
        in all list commands, let's retrieve these entity name keys
        from received data, add it as a 'name'-key value to entry and return
        only values of respective entries as a list:
        {                               {
          "entity_name_1": {...},          "entity_name_1":
                ...                           {"name": "entity_name_1", ...},
                ...                --->                ...
                ...                                    ...
          "entity_name_n": {...}           "entity_name_n":
                                              {"name": "entity_name_n", ...}
        }                               }

        ---> [{"name": "entity_name_1", ...}, {"name": "entity_name_n", ...}]

        :param data: A map that maps entity names to respective entries
        :return:     List of dictionaries containing values of entries.
        """
    for entity_item in data:
        data[entity_item]['name'] = entity_item
    return data.values()


def list_available_devices():
    """ List all available devices for the respective backend """
    raise NotImplementedError()


def batch(qs, batch_size=1000):
    """
    Returns a ( start, end, total, queryset ) tuple for each batch in the given
    queryset.

    Usage:
        # Make sure to order your querset
        article_qs = Article.objects.order_by('id')
        for start, end, total, qs in batch_qs(article_qs):
            print "Now processing %s - %s of %s" % (start + 1, end, total)
            for article in qs:
                print article.body
    """
    total = qs.count()
    for start in range(0, total, batch_size):
        end = min(start + batch_size, total)
        yield start, end, total, qs[start:end]


def add_prefix_to_lines(_lines, _prefix):
    """
        add_prefix_to_lines()
        ________________________________________________________________________

        Add a prefix to each line in _lines.

            e.g. : ["abc", "def"] -> ["PREFIXabc", "PREFIXdef"]
        ________________________________________________________________________

        PARAMETERS :
            ▪ _lines        : a list of (str)lines
            ▪ _prefix       : (str)the prefix to be added

        RETURNED VALUE :
            o a list of strings
    """
    res = []
    for line in _lines:
        res.append(_prefix + line)
    return res


def get_content_disposition(mimeobj):
    """Return the message's content-disposition if it exists, or None.

    Backport of py3.5 :func:`~email.message.Message.get_content_disposition`
    """
    value = mimeobj.get('content-disposition')
    if value is None:
        return None
    return str(value).partition(';')[0].strip().lower()


def get_time(timeformat='%m-%d-%y_%T%p', raw=False, filename_friendly=False,
    replacement_seperator='-'):
    """
    Gets current time in local time zone.
    if raw: True then raw datetime object returned without formatting.
    if filename_friendly: replace ':' with replacement_separator
    """
    from datetime import datetime
    from pytz import timezone
    from tzlocal import get_localzone
    now_utc = datetime.now(timezone('UTC'))
    now_local = now_utc.astimezone(get_localzone())
    if raw == True:
        return now_local
    else:
        now = now_local.strftime(timeformat)
    if filename_friendly == True:
        return now.replace(':', replacement_seperator).lower()
    else:
        return now


def metric_set_max(key, value):
    """Sets metric value if it is greater that the current one.

    :param str|unicode key:

    :param int|long value:

    :rtype: bool
    """
    return False


def quartal_name(quartal):
    """Returns the quartal name for ETH juniors Salesforce"""
    quartal_names = {(1): 'Q1', (2): 'Q2', (3): 'Q3', (4): 'Q4'}
    return quartal_names[quartal]


def strings(n, k):
    """Number of DUSWR of k items from a set of n items."""
    return pow(n, k)


def lambd_tris_trisH_GT17simopt(T, P):
    """n-c: tris trisH [GT17simopt]."""
    lambd = 0.06306
    valid = T == 298.15
    return lambd, valid


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

        :param SmartSyncCreateAdminPrivilegeReportDetails val:
        :rtype: EventDetails
        """
    return cls('smart_sync_create_admin_privilege_report_details', val)


def operation():
    """Context menu for item operations

    """
    pass


@staticmethod
def get_bool(config, key, default):
    """
        helper method - get the boolean value from a config entry,
                        which could be either boolean or string

        as we might get from the json a real boolean or a string, we use
        the %r to print the representation to generalize the processing
        """
    as_str = str(config.get(key, default))
    return as_str.lower() == 'true'


def count(data_store, record_selector):
    """Get the number of selected records in the data store

    Args:
        data_store: a DataStore object
        record_selector: a RecordSelector object. It defines which records
            should be processed.
    Returns:
        number
    """
    n = 0
    for _ in record_selector.get_records(data_store):
        n = n + 1
    return n


def __call__(context):
    """Returns a default value for the field."""


def dsmr_transform(value):
    """Transform DSMR version value to right format."""
    if value.isdigit():
        return float(value) / 10
    return value


@classmethod
def limit(cls, refs, hints):
    """Limit a list of entities.

        The underlying driver layer may have already truncated the collection
        for us, but in case it was unable to handle truncation we check here.

        :param refs: the list of members of the collection
        :param hints: hints, containing, among other things, the limit
                      requested

        :returns: boolean indicating whether the list was truncated, as well
                  as the list of (truncated if necessary) entities.

        """
    NOT_LIMITED = False
    LIMITED = True
    if hints is None or hints.limit is None:
        return NOT_LIMITED, refs
    if hints.limit.get('truncated', False):
        return LIMITED, refs
    if len(refs) > hints.limit['limit']:
        return LIMITED, refs[:hints.limit['limit']]
    return NOT_LIMITED, refs


@classmethod
def getVar(cls, varName, defaultValue=None):
    """ Return the value of a given variable. """
    return cls._vars.get(varName, defaultValue)


def describe_alarms_for_metric(MetricName=None, Namespace=None, Statistic=
    None, ExtendedStatistic=None, Dimensions=None, Period=None, Unit=None):
    """
    Retrieves the alarms for the specified metric. Specify a statistic, period, or unit to filter the results.
    See also: AWS API Documentation

    :example: response = client.describe_alarms_for_metric(
        MetricName='string',
        Namespace='string',
        Statistic='SampleCount'|'Average'|'Sum'|'Minimum'|'Maximum',
        ExtendedStatistic='string',
        Dimensions=[
            {
                'Name': 'string',
                'Value': 'string'
            },
        ],
        Period=123,
        Unit='Seconds'|'Microseconds'|'Milliseconds'|'Bytes'|'Kilobytes'|'Megabytes'|'Gigabytes'|'Terabytes'|'Bits'|'Kilobits'|'Megabits'|'Gigabits'|'Terabits'|'Percent'|'Count'|'Bytes/Second'|'Kilobytes/Second'|'Megabytes/Second'|'Gigabytes/Second'|'Terabytes/Second'|'Bits/Second'|'Kilobits/Second'|'Megabits/Second'|'Gigabits/Second'|'Terabits/Second'|'Count/Second'|'None'
    )

    :type MetricName: string
    :param MetricName: [REQUIRED]
            The name of the metric.

    :type Namespace: string
    :param Namespace: [REQUIRED]
            The namespace of the metric.

    :type Statistic: string
    :param Statistic: The statistic for the metric, other than percentiles. For percentile statistics, use ExtendedStatistics .

    :type ExtendedStatistic: string
    :param ExtendedStatistic: The percentile statistic for the metric. Specify a value between p0.0 and p100.

    :type Dimensions: list
    :param Dimensions: The dimensions associated with the metric. If the metric has any associated dimensions, you must specify them in order for the call to succeed.
            (dict) --Expands the identity of a metric.
            Name (string) -- [REQUIRED]The name of the dimension.
            Value (string) -- [REQUIRED]The value representing the dimension measurement.

    :type Period: integer
    :param Period: The period, in seconds, over which the statistic is applied.

    :type Unit: string
    :param Unit: The unit for the metric.

    :rtype: dict
    :return: {
        'MetricAlarms': [
            {
                'AlarmName': 'string',
                'AlarmArn': 'string',
                'AlarmDescription': 'string',
                'AlarmConfigurationUpdatedTimestamp': datetime(2015, 1, 1),
                'ActionsEnabled': True|False,
                'OKActions': [
                    'string',
                ],
                'AlarmActions': [
                    'string',
                ],
                'InsufficientDataActions': [
                    'string',
                ],
                'StateValue': 'OK'|'ALARM'|'INSUFFICIENT_DATA',
                'StateReason': 'string',
                'StateReasonData': 'string',
                'StateUpdatedTimestamp': datetime(2015, 1, 1),
                'MetricName': 'string',
                'Namespace': 'string',
                'Statistic': 'SampleCount'|'Average'|'Sum'|'Minimum'|'Maximum',
                'ExtendedStatistic': 'string',
                'Dimensions': [
                    {
                        'Name': 'string',
                        'Value': 'string'
                    },
                ],
                'Period': 123,
                'Unit': 'Seconds'|'Microseconds'|'Milliseconds'|'Bytes'|'Kilobytes'|'Megabytes'|'Gigabytes'|'Terabytes'|'Bits'|'Kilobits'|'Megabits'|'Gigabits'|'Terabits'|'Percent'|'Count'|'Bytes/Second'|'Kilobytes/Second'|'Megabytes/Second'|'Gigabytes/Second'|'Terabytes/Second'|'Bits/Second'|'Kilobits/Second'|'Megabits/Second'|'Gigabits/Second'|'Terabits/Second'|'Count/Second'|'None',
                'EvaluationPeriods': 123,
                'Threshold': 123.0,
                'ComparisonOperator': 'GreaterThanOrEqualToThreshold'|'GreaterThanThreshold'|'LessThanThreshold'|'LessThanOrEqualToThreshold',
                'TreatMissingData': 'string',
                'EvaluateLowSampleCountPercentile': 'string'
            },
        ]
    }

    :returns:
    (string) --

    """
    pass


def set_bit_k(int_val, k):
    """Sets the bit at offset k"""
    return int_val | 1 << k


def rotfft_from_vecfft(vx_fft, vy_fft, vz_fft, kx, ky, kz):
    """Compute the curl of a vector (in spectral space)"""
    return 1.0j * (ky * vz_fft + kz * vy_fft), 1.0j * (kz * vx_fft + kx *
        vz_fft), 1.0j * (kx * vy_fft + ky * vx_fft)


def provides(varmap):
    """Return a minimal ``provides`` list from the setup vars.
    """
    try:
        return ['{} ({})'.format(varmap['name'], varmap['version'])]
    except KeyError:
        return [varmap['name']]


def items():
    """Return sequence of (key, value) elements."""


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

        :param DomainInvitesDeclineRequestToJoinTeamType val:
        :rtype: EventType
        """
    return cls('domain_invites_decline_request_to_join_team', val)


@staticmethod
def row_path_builder(path='', row=''):
    """
        Builds row and path query.
        :param path:
            Landsat path. Must be three digits
        :type path:
            String
        :param row:
            Landsat row. Must be three digits
        :type row:
            String
        :returns:
            String
        """
    return 'path:%s+AND+row:%s' % (path, row)