def get_binsize(bins):
    """
    Infer bin size from a bin DataFrame. Assumes that the last bin of each
    contig is allowed to differ in size from the rest.

    Returns
    -------
    int or None if bins are non-uniform

    """
    sizes = set()
    for chrom, group in bins.groupby('chrom'):
        sizes.update((group['end'] - group['start']).iloc[:-1].unique())
        if len(sizes) > 1:
            return None
    if len(sizes) == 1:
        return next(iter(sizes))
    else:
        return None


def decorate(func, fwrapped):
    """A wrapper call of decorator package, differs to call time

    Parameters
    ----------
    func : function
        The original function

    fwrapped : function
        The wrapped function
    """
    import decorator
    return decorator.decorate(func, fwrapped)


def Title(v):
    """Title case a string.

    >>> s = Schema(Title)
    >>> s('hello world')
    'Hello World'
    """
    return str(v).title()


def c_delete(api, args, verbose=False):
    """
Delete an object::

    usage: cdstar delete <URL>
"""
    obj = api.get_object(args['<URL>'].split('/')[-1])
    obj.delete()
    if verbose:
        return ['deleted object at', api.url(obj)]


def update():
    """Adjust step and update actions."""


def binance_interval(interval):
    """ Return the time interval in the specific format allowed by Binance.

    Parameters
    ----------
    interval : int
        Must be in seconds as 60, 180, 300, 900, 1800, 3600, 7200, 14400,
        21600, 28800, 43200, 86400, 259200, 604800, 2592000.

    Returns
    -------
    form : str
        Specific format allowed by Binance.

    Examples
    --------
    >>> binance_interval(7200)
    '2h'

    """
    if interval / 60 in [1, 3, 5, 15, 30]:
        return '{}m'.format(int(interval / 60))
    elif interval / 3600 in [1, 2, 4, 6, 8, 12]:
        return '{}h'.format(int(interval / 3600))
    elif interval / 86400 in [1, 3]:
        return '{}d'.format(int(interval / 86400))
    elif interval == 604800:
        return '1w'
    elif interval == 2592000:
        return '1M'
    else:
        print('No format allowed.')


def is_binary_str(var):
    """
    Check whether var is of type BinaryStr.

    :param var: The variable to check.
    :return: ``True`` if var is a :any:`BinaryStr`.
    """
    return isinstance(var, bytes) or isinstance(var, bytearray) or isinstance(
        var, memoryview)


def theta_CO3_HCO3_HMW84(T, P):
    """a-a': carbonate bicarbonate [HMW84]."""
    theta = -0.04
    valid = T == 298.15
    return theta, valid


@staticmethod
def _reduce(res, result_single_frame):
    """ 'append' action for a time series"""
    res.append(result_single_frame)
    return res


@staticmethod
def simplify_service_access_result(service_access_list: list):
    """
        Simplifies AWS's service_last_accessed object by keeping only the relevant fields of the services that were in use
        :param service_access_list: List of service_last_accessed objects as received from the API
        :return: A list of objects of the format {"ServiceNamespace": ..., "LastAccessed": ...}, and only those that were in use
        """
    return list(map(lambda last_access: {'ServiceNamespace': last_access[
        'ServiceNamespace'], 'LastAccessed': last_access[
        'LastAuthenticated']}, filter(lambda last_access: last_access[
        'TotalAuthenticatedEntities'] > 0, service_access_list)))


@classmethod
def from_data(cls, data):
    """Construct a ellipse from its data representation.

        Parameters
        ----------
        data : dict
            The data dictionary.

        Returns
        -------
        :class:`compas.geometry.Ellipse`
            The constructed ellipse.

        Examples
        --------
        >>> from compas.geometry import Ellipse
        >>> data = {'plane': [[0.0, 0.0, 0.0], [0.0, 0.0, 1.0]], 'major': 2.0, 'minor': 1.0}
        >>> ellipse = Ellipse.from_data(data)
        """
    return cls(data['plane'], data['minor'], data['minor'])


def filter_assembly(assembly_file, minimum_coverage, coverage_info, output_file
    ):
    """Generates a filtered assembly file.

    This function generates a filtered assembly file based on an original
    assembly and a minimum coverage threshold.

    Parameters
    ----------
    assembly_file : str
        Path to original assembly file.
    minimum_coverage : int or float
        Minimum coverage required for a contig to pass the filter.
    coverage_info : OrderedDict or dict
        Dictionary containing the coverage information for each contig.
    output_file : str
        Path where the filtered assembly file will be generated.

    """
    write_flag = False
    with open(assembly_file) as fh, open(output_file, 'w') as out_fh:
        for line in fh:
            if line.startswith('>'):
                write_flag = False
                header = line.strip()[1:]
                contig_cov = coverage_info[header]['cov']
                if contig_cov >= minimum_coverage:
                    write_flag = True
                    out_fh.write(line)
            elif write_flag:
                out_fh.write(line)


def delete_launch_configuration(LaunchConfigurationName=None):
    """
    Deletes the specified launch configuration.
    The launch configuration must not be attached to an Auto Scaling group. When this call completes, the launch configuration is no longer available for use.
    See also: AWS API Documentation

    Examples
    This example deletes the specified launch configuration.
    Expected Output:

    :example: response = client.delete_launch_configuration(
        LaunchConfigurationName='string'
    )

    :type LaunchConfigurationName: string
    :param LaunchConfigurationName: [REQUIRED]
            The name of the launch configuration.

    :return: response = client.delete_launch_configuration(
        LaunchConfigurationName='my-launch-config',
    )

    print(response)

    """
    pass


def comment_import(r, unused_dot_list):
    """Comment out import for {dot_str}."""
    unused_dot_str = '.'.join(unused_dot_list)
    for n in r('ImportNode'):
        if n.names()[0] == unused_dot_str:
            n.replace('#{}# {}'.format('!', str(n)))
            break


def is_numeric(value=''):
    """
    Check if the value is numeric.

    Parameters
    ----------
    value : str
        Value to check.

    Returns
    -------
    boolean
        Whether the value is numeric.
    """
    if isinstance(value, str):
        try:
            float(value) if '.' in value else int(value)
        except ValueError:
            return False
    return True


@staticmethod
def _get_last_six_bits_of_pointer(label_length: bytes) ->bytes:
    """
        Retrieves the last six bits of the label_length bytes, to be used in decoding the pointer.

        :param label_length: the label_length bytes that contain the pointer.
        :return: the last six bits of the label_length bytes
        """
    bitmask: int = int.from_bytes(b'?', 'big')
    label_length_as_int: int = int.from_bytes(label_length, 'big')
    return (label_length_as_int & bitmask).to_bytes(1, 'big')


def _dummyProgressCallback(progress):
    """ A callback to indicate progress that does nothing. """
    pass


def toMiles(x):
    """
    Converts x from Kilometers to Miles
    :param x:
    :return: x / 1.609
     >>> toMiles(1)
    0.621371
    """
    return x / 1.609


@classmethod
def enable(cls):
    """Enables headless events for the target.
        """
    return cls.build_send_payload('enable', {}), None


def _get_type_name(type_):
    """Return a displayable name for the type.

    Args:
        type_: A class object.

    Returns:
        A string value describing the class name that can be used in a natural
        language sentence.
    """
    name = repr(type_)
    if name.startswith('<'):
        name = getattr(type_, '__qualname__', getattr(type_, '__name__', ''))
    return name.rsplit('.', 1)[-1] or repr(type_)


@staticmethod
def permalink(mlist, msg):
    """See `IArchiver`."""
    return None


def ix_name(table_name, column_name):
    """Returns the name that will be used in the database for an index key, given:

       :arg table_name: The name of the table to which the index belongs.
       :arg column_name: The name of the column that is indexed.
    """
    return 'ix_%s_%s' % (table_name, column_name)


@staticmethod
def _migration_file_name(migration_version):
    """Create migration file name based on migration version."""
    return str(migration_version) + '.json'


def get_role_permission(role):
    """Common function for getting the permission froms arg

    This format is 'openstack.roles.xxx' and 'xxx' is a real role name.

    :returns:
        String like "openstack.roles.admin"
        If role is None, this will return None.

    """
    return 'openstack.roles.%s' % role.lower()


def urlsplit(url):
    """Split an arbitrary url into protocol, host, rest

    The standard urlsplit does not want to provide 'netloc' for arbitrary
    protocols, this works around that.

    :param url: The url to split into component parts
    """
    proto, rest = url.split(':', 1)
    host = ''
    if rest[:2] == '//':
        host, rest = rest[2:].split('/', 1)
        rest = '/' + rest
    return proto, host, rest


@classmethod
def get_master_process(cls):
    """
        Return True if we are the master process, False otherwise.
        :return bool
        :rtype bool
        """
    return cls._master_process


@classmethod
def fromkeys(cls, iterable, value=None):
    """OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
        and values equal to v (which defaults to None).

        """
    d = cls()
    for key in iterable:
        d[key] = value
    return d


def create(request):
    """
        Called when a node creation request has been received.

        @param request: The publish-subscribe request.
        @type request: L{wokkel.pubsub.PubSubRequest}
        @return: A deferred that fires with a C{unicode} that represents
                 the identifier of the new node.
        @rtype: L{Deferred<twisted.internet.defer.Deferred>}
        """


def map_array_3d(array, f):
    """
    Map a function over the whole array.  Side effects the array.  No
    return value.
    """
    for i in range(len(array)):
        for j in range(len(array[0])):
            for k in range(len(array[0][0])):
                array[i][j][k] = f(array[i][j][k])


@staticmethod
def get_or_new_from_json_dict(data, cls):
    """Get `cls` object w/ deserialization from json if needed.
        If data is instance of cls, return data.
        Else if data is instance of dict, create instance from dict.
        Else, return None.
        :param data:
        :param cls:
        :rtype: object
        :return:
        """
    if isinstance(data, cls):
        return data
    elif isinstance(data, dict):
        return cls.new_from_json_dict(data)
    return None


def get_verbose_details(account):
    """
    Return details for verbose output.

    :param safe.model.Account account: Account for which to get details
    :return: Sequence of 2-tuples with details for the UI
    :rtype: :func:`tuple` of 2-tuples ``(field name, info)`` where both
            items are strings
    """
    questions = 'no questions'
    questions_count = account.question_query.count()
    if questions_count > 0:
        questions = '%i question' % questions_count
        if questions_count > 1:
            questions += 's'
    codes = 'no backup codes'
    codes_count = account.code_query.count()
    if codes_count > 0:
        codes = '%i backup code' % codes_count
        if codes_count > 1:
            codes += 's'
        used_codes = 'none used'
        used_codes_count = account.code_query.filter_by(used=True).count()
        if used_codes_count > 0:
            used_codes = '%i used' % used_codes_count
        codes += ' (%s)' % used_codes
    security = '%s, %s' % (questions, codes)
    fmt = 'password is %s, question is %s'
    password_policy = '<not set>'
    if account.password_policy:
        password_policy = '"%s"' % account.password_policy.name
    question_policy = '<not set>'
    if account.question_policy:
        question_policy = '"%s"' % account.question_policy.name
    policies = fmt % (password_policy, question_policy)
    return ('security', security), ('policies', policies)


@classmethod
def as_bounding(cls, points):
    """Create a Rectangle object from a selection of bounded points.

        :Parameters:
            `points` : Vectors
                The points to bound.

        """
    xs, ys = zip(*points)
    lo = min(xs), min(ys)
    hi = max(xs), max(ys)
    return cls(lo, hi)


def literal_string(s):
    """
    Return s as a postgres literal string
    """
    return u"'" + s.replace(u"'", u"''").replace(u'\x00', '') + u"'"


def _get_sequence_list(sequences, minimum_len):
    """Helper funtion to return a set of unique sequences."""
    seq_list = set([])
    for seq in sequences:
        seq = str(seq).replace('*', '')
        if len(seq) > minimum_len:
            seq_list.add(seq)
    return seq_list


def write_executor_id(num):
    """Write executor_id into a local file in the executor's current working directory"""
    with open('executor_id', 'w') as f:
        f.write(str(num))


def remove_tags_from_resource(ResourceName=None, TagKeys=None):
    """
    Removes metadata tags from an Amazon RDS resource.
    For an overview on tagging an Amazon RDS resource, see Tagging Amazon RDS Resources .
    See also: AWS API Documentation

    Examples
    This example removes the specified tag associated with the specified DB option group.
    Expected Output:

    :example: response = client.remove_tags_from_resource(
        ResourceName='string',
        TagKeys=[
            'string',
        ]
    )

    :type ResourceName: string
    :param ResourceName: [REQUIRED]
            The Amazon RDS resource the tags will be removed from. This value is an Amazon Resource Name (ARN). For information about creating an ARN, see Constructing an RDS Amazon Resource Name (ARN) .

    :type TagKeys: list
    :param TagKeys: [REQUIRED]
            The tag key (name) of the tag to be removed.
            (string) --

    :return: response = client.remove_tags_from_resource(
        ResourceName='arn:aws:rds:us-east-1:992648334831:og:mydboptiongroup',
        TagKeys=[
            'MyKey',
        ],
    )

    print(response)

    """
    pass


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

        :param SharingUserError val:
        :rtype: ListFileMembersContinueError
        """
    return cls('user_error', val)


def add_bio_tools(json):
    """Add additional fields that require logic for bio.tools"""
    if 'link' in json:
        for l in json['link']:
            if l['type'] == 'Repository':
                json['schema:codeRepository'] = {'@id': l['url']}


def _sanitize(hex_str, comment_strings=None, ignore_strings=None):
    """
    Sanitize string input before attempting to write to file.

    :param hex_str: the string input to sanitize
    :param comment_strings:  a tuple of strings identifying comment characters
    :param ignore_strings:  a tuple of strings to ignore in the input
    :return: the sanitized string or None
    """
    hex_str = hex_str.strip()
    if not hex_str:
        return None
    if comment_strings:
        for comment_string in comment_strings:
            if hex_str.startswith(comment_string):
                return None
            else:
                hex_str = hex_str.split(comment_string)[0]
    hex_id = '0x'
    if ignore_strings:
        ignore_strings += hex_id,
    else:
        ignore_strings = hex_id,
    for string_to_remove in ignore_strings:
        hex_str = hex_str.replace(string_to_remove, '')
    return ''.join(hex_str.split())


def has_params(m):
    """Check if `m` has at least one parameter"""
    return len(list(m.parameters())) > 0


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

        :param RemoveFolderMemberError val:
        :rtype: RemoveMemberJobStatus
        """
    return cls('failed', val)


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 success_check(filename):
    """Parse the given log file and check whether the script execution
    was successful or not

    Parameters
    ----------
    filename : str
        Name of the log file to parse

    Returns
    -------
    execution : str
        ``success`` or ``failure``
    """
    with open(filename, 'r') as file_obj:
        all_lines = file_obj.readlines()
    final_line = all_lines[-1]
    if 'complete' in final_line.lower():
        execution = 'success'
    else:
        execution = 'failure'
    return execution


def _check_if_list_of_featuregroups_contains_featuregroup(featuregroups,
    featuregroup_name, version):
    """
    Check if a list of featuregroup contains a featuregroup with a particular name and version

    Args:
        :featuregroups: the list of featuregroups to search through
        :featuregroup_name: the name of the featuregroup
        :version: the featuregroup version

    Returns:
        boolean indicating whether the featuregroup name and version exists in the list
    """
    match_bool = False
    for fg in featuregroups:
        if fg.name == featuregroup_name and fg.version == version:
            match_bool = True
    return match_bool


@staticmethod
def fraction_possible_dimer(system_parameters: dict, y):
    """  Readout as fraction total possible dimer  """
    return 'Fraction possible dimer', y / (system_parameters['p'] / 2.0)


def vertex_paint_toggle():
    """Toggle the vertex paint mode in 3D view

    """
    pass


def stat_view(bull, bear, doji):
    """ Retorna a view stat."""
    return 'verde %i vermelho %i doji %i' % (bull, bear, doji)


def describe_stack_summary(StackId=None):
    """
    Describes the number of layers and apps in a specified stack, and the number of instances in each state, such as running_setup or online .
    See also: AWS API Documentation

    :example: response = client.describe_stack_summary(
        StackId='string'
    )

    :type StackId: string
    :param StackId: [REQUIRED]
            The stack ID.

    :rtype: dict
    :return: {
        'StackSummary': {
            'StackId': 'string',
            'Name': 'string',
            'Arn': 'string',
            'LayersCount': 123,
            'AppsCount': 123,
            'InstancesCount': {
                'Assigning': 123,
                'Booting': 123,
                'ConnectionLost': 123,
                'Deregistering': 123,
                'Online': 123,
                'Pending': 123,
                'Rebooting': 123,
                'Registered': 123,
                'Registering': 123,
                'Requested': 123,
                'RunningSetup': 123,
                'SetupFailed': 123,
                'ShuttingDown': 123,
                'StartFailed': 123,
                'Stopped': 123,
                'Stopping': 123,
                'Terminated': 123,
                'Terminating': 123,
                'Unassigning': 123
            }
        }
    }

    """
    pass


def getMDF(rawEMGPowerSpectrum, frequencies):
    """ Obtain the Median Frequency of the PSD.

        MDF is a frequency at which the spectrum is divided into two regions with equal amplitude, in other words, MDF is half of TTP feature

        * Input:
            * raw EMG Power Spectrum
            * frequencies
        * Output:
            * Median Frequency  (Hz)

        :param rawEMGPowerSpectrum: power spectrum of the EMG signal
        :type rawEMGPowerSpectrum: list
        :param frequencies: frequencies of the PSD
        :type frequencies: list
        :return: median frequency of the EMG power spectrum
        :rtype: float
    """
    MDP = sum(rawEMGPowerSpectrum) * (1 / 2)
    for i in range(1, len(rawEMGPowerSpectrum)):
        if sum(rawEMGPowerSpectrum[0:i]) >= MDP:
            return frequencies[i]


@classmethod
def get_default_session_class(cls):
    """Get the default session class for :py:class:`JsonApiService`.

        Returns
        -------
        JsonApiService
            The default session class, which is :py:class:`JsonApiService` itself or
            a derived class from :py:class:`JsonApiService`.
        """
    return cls._session_class


def describe_reserved_instances_modifications(ReservedInstancesModificationIds
    =None, NextToken=None, Filters=None):
    """
    Describes the modifications made to your Reserved Instances. If no parameter is specified, information about all your Reserved Instances modification requests is returned. If a modification ID is specified, only information about the specific modification is returned.
    For more information, see Modifying Reserved Instances in the Amazon Elastic Compute Cloud User Guide.
    See also: AWS API Documentation

    :example: response = client.describe_reserved_instances_modifications(
        ReservedInstancesModificationIds=[
            'string',
        ],
        NextToken='string',
        Filters=[
            {
                'Name': 'string',
                'Values': [
                    'string',
                ]
            },
        ]
    )

    :type ReservedInstancesModificationIds: list
    :param ReservedInstancesModificationIds: IDs for the submitted modification request.
            (string) --

    :type NextToken: string
    :param NextToken: The token to retrieve the next page of results.

    :type Filters: list
    :param Filters: One or more filters.
            client-token - The idempotency token for the modification request.
            create-date - The time when the modification request was created.
            effective-date - The time when the modification becomes effective.
            modification-result.reserved-instances-id - The ID for the Reserved Instances created as part of the modification request. This ID is only available when the status of the modification is fulfilled .
            modification-result.target-configuration.availability-zone - The Availability Zone for the new Reserved Instances.
            modification-result.target-configuration.instance-count - The number of new Reserved Instances.
            modification-result.target-configuration.instance-type - The instance type of the new Reserved Instances.
            modification-result.target-configuration.platform - The network platform of the new Reserved Instances (EC2-Classic | EC2-VPC ).
            reserved-instances-id - The ID of the Reserved Instances modified.
            reserved-instances-modification-id - The ID of the modification request.
            status - The status of the Reserved Instances modification request (processing | fulfilled | failed ).
            status-message - The reason for the status.
            update-date - The time when the modification request was last updated.
            (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) --

    :rtype: dict
    :return: {
        'ReservedInstancesModifications': [
            {
                'ReservedInstancesModificationId': 'string',
                'ReservedInstancesIds': [
                    {
                        'ReservedInstancesId': 'string'
                    },
                ],
                'ModificationResults': [
                    {
                        'ReservedInstancesId': 'string',
                        'TargetConfiguration': {
                            'AvailabilityZone': 'string',
                            'Platform': 'string',
                            'InstanceCount': 123,
                            'InstanceType': 't1.micro'|'t2.nano'|'t2.micro'|'t2.small'|'t2.medium'|'t2.large'|'t2.xlarge'|'t2.2xlarge'|'m1.small'|'m1.medium'|'m1.large'|'m1.xlarge'|'m3.medium'|'m3.large'|'m3.xlarge'|'m3.2xlarge'|'m4.large'|'m4.xlarge'|'m4.2xlarge'|'m4.4xlarge'|'m4.10xlarge'|'m4.16xlarge'|'m2.xlarge'|'m2.2xlarge'|'m2.4xlarge'|'cr1.8xlarge'|'r3.large'|'r3.xlarge'|'r3.2xlarge'|'r3.4xlarge'|'r3.8xlarge'|'r4.large'|'r4.xlarge'|'r4.2xlarge'|'r4.4xlarge'|'r4.8xlarge'|'r4.16xlarge'|'x1.16xlarge'|'x1.32xlarge'|'i2.xlarge'|'i2.2xlarge'|'i2.4xlarge'|'i2.8xlarge'|'i3.large'|'i3.xlarge'|'i3.2xlarge'|'i3.4xlarge'|'i3.8xlarge'|'i3.16xlarge'|'hi1.4xlarge'|'hs1.8xlarge'|'c1.medium'|'c1.xlarge'|'c3.large'|'c3.xlarge'|'c3.2xlarge'|'c3.4xlarge'|'c3.8xlarge'|'c4.large'|'c4.xlarge'|'c4.2xlarge'|'c4.4xlarge'|'c4.8xlarge'|'cc1.4xlarge'|'cc2.8xlarge'|'g2.2xlarge'|'g2.8xlarge'|'cg1.4xlarge'|'p2.xlarge'|'p2.8xlarge'|'p2.16xlarge'|'d2.xlarge'|'d2.2xlarge'|'d2.4xlarge'|'d2.8xlarge'|'f1.2xlarge'|'f1.16xlarge',
                            'Scope': 'Availability Zone'|'Region'
                        }
                    },
                ],
                'CreateDate': datetime(2015, 1, 1),
                'UpdateDate': datetime(2015, 1, 1),
                'EffectiveDate': datetime(2015, 1, 1),
                'Status': 'string',
                'StatusMessage': 'string',
                'ClientToken': 'string'
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


def get_intensity(r, g, b):
    """Get the gray level intensity of the given rgb triplet."""
    return int(round(255 * (0.3 * r + 0.59 * g + 0.11 * b)))


@staticmethod
def load_iptags(iptags, transceiver, progress_bar):
    """ Loads all the IP tags individually.

        :param iptags: the IP tags to be loaded.
        :param transceiver: the transceiver object
        :rtype: None
        """
    for ip_tag in progress_bar.over(iptags, False):
        transceiver.set_ip_tag(ip_tag)


@classmethod
def run_hooks(cls, hook_type, *args, **kwargs):
    """Run all hooks of specified type.

        :param cls: class that registers hooks
        :param hook_type: hook type, e.g., '__pre_parse_args__'
        :param args: args to be passed to every hook function
        :param kwargs: kwargs to be passed to every hook function
        """
    hook_funcs = cls._hooks_map.get(hook_type) or []
    for hook_func in hook_funcs:
        hook_func(*args, **kwargs)


@staticmethod
def get_next_symbol(curr_future_symbol: str) ->str:
    """
        >>> assert(EminiFuture.get_next_symbol('ESZ8') == 'ESH9')
        """
    month = curr_future_symbol[2]
    year = int(curr_future_symbol[3])
    next_month = {'Z': 'H', 'H': 'M', 'M': 'U', 'U': 'Z'}[month]
    next_year = year if next_month != 'H' else year + 1
    if next_year == 10:
        next_year == 0
    return f'ES{next_month}{next_year}'


@classmethod
def send_cloud_message(cls, business_id=None, store_id=None, class_name=
    None, package_name=None, device_id=None, serial_number=None, data='{}',
    collapse_key=None, ttl=900):
    """
        Send a message from the cloud to your application running at a Poynt terminal.

        Keyword arguments:
        business_id (str): the business ID
        store_id (str): the store ID
        class_name (str): the class name of the receiver in your app
        package_name (str): the package name of your app
        device_id (str): the device ID
        serial_number (str): the serial number
        data (str, optional): the data to send. defaults to {}
        collapse_key (str, optional): dedupe messages on this key
        ttl (int, optional): how long until the cloud message expires. defaults
                             to 900 seconds
        """
    message = {'businessId': business_id, 'storeId': store_id, 'deviceId':
        device_id, 'recipient': {'className': class_name, 'packageName':
        package_name}}
    if serial_number is not None:
        message['serialNum'] = serial_number
    if collapse_key is not None:
        message['collapseKey'] = collapse_key
    if ttl is not None:
        message['ttl'] = ttl
    if data is not None:
        message['data'] = data
    return cls.send_raw_cloud_message(message)


def send(message, type=u'message'):
    """Send a message to this source.

        Message can either be a unicode string or an IMessage object.

        """


def float_f(f):
    """Formats a float for printing to std out."""
    return '{:.0f}'.format(f)


def qualifyKind(kind):
    """
    Qualifies the breathe ``kind`` and returns an qualifier string describing this
    to be used for the text output (e.g. in generated file headings and link names).

    The output for a given kind is as follows:

    +-------------+------------------+
    | Input Kind  | Output Qualifier |
    +=============+==================+
    | "class"     | "Class"          |
    +-------------+------------------+
    | "define"    | "Define"         |
    +-------------+------------------+
    | "enum"      | "Enum"           |
    +-------------+------------------+
    | "enumvalue" | "Enumvalue"      |
    +-------------+------------------+
    | "file"      | "File"           |
    +-------------+------------------+
    | "function"  | "Function"       |
    +-------------+------------------+
    | "group"     | "Group"          |
    +-------------+------------------+
    | "namespace" | "Namespace"      |
    +-------------+------------------+
    | "struct"    | "Struct"         |
    +-------------+------------------+
    | "typedef"   | "Typedef"        |
    +-------------+------------------+
    | "union"     | "Union"          |
    +-------------+------------------+
    | "variable"  | "Variable"       |
    +-------------+------------------+

    The following breathe kinds are ignored:

    - "autodoxygenfile"
    - "doxygenindex"
    - "autodoxygenindex"

    Note also that although a return value is generated, neither "enumvalue" nor
    "group" are actually used.

    :Parameters:
        ``kind`` (str)
            The return value of a Breathe ``compound`` object's ``get_kind()`` method.

    :Return (str):
        The qualifying string that will be used to build the reStructuredText titles and
        other qualifying names.  If the empty string is returned then it was not
        recognized.
    """
    if kind == 'dir':
        return 'Directory'
    else:
        return kind.capitalize()


def _splitrange(a, b):
    """Split range with bounds a and b into two ranges at 0 and return two
    tuples of numbers for use as startdepth and stopdepth arguments of
    revancestors and revdescendants.

    >>> _splitrange(-10, -5)     # [-10:-5]
    ((5, 11), (None, None))
    >>> _splitrange(5, 10)       # [5:10]
    ((None, None), (5, 11))
    >>> _splitrange(-10, 10)     # [-10:10]
    ((0, 11), (0, 11))
    >>> _splitrange(-10, 0)      # [-10:0]
    ((0, 11), (None, None))
    >>> _splitrange(0, 10)       # [0:10]
    ((None, None), (0, 11))
    >>> _splitrange(0, 0)        # [0:0]
    ((0, 1), (None, None))
    >>> _splitrange(1, -1)       # [1:-1]
    ((None, None), (None, None))
    """
    ancdepths = None, None
    descdepths = None, None
    if a == b == 0:
        ancdepths = 0, 1
    if a < 0:
        ancdepths = -min(b, 0), -a + 1
    if b > 0:
        descdepths = max(a, 0), b + 1
    return ancdepths, descdepths


def get_template_info_from_metadata_format_and_template(
    harvester_metadata_format, template):
    """Get template information from metadata format and template
    Args:
        harvester_metadata_format: Metadata format
        template: Related template

    Returns:
        Template information.

    """
    name = harvester_metadata_format.get_display_name()
    return_value = {'id': template.id if template is not None else '',
        'name': name, 'hash': harvester_metadata_format.hash}
    return return_value


def start_criteria(date, flags):
    """Check start criteria

    Args:
        date (datetime): date of current element
        flags (dict): List of flags

    Returns:
        bool: returns true if start criteria is achieved
    """
    result = True
    if 'from_date' in flags:
        result = date >= flags['from_date']
    return result


def integer_as_number_of_bits(size):
    """Returns the minimum number of bits needed to fit given positive
    integer.

    """
    if size == 0:
        return 0
    else:
        return size.bit_length()


@staticmethod
def dumps(data, pretty=False, test=None):
    """Return structured data as a string.

        If pretty is true, prettify.
        """
    return data


def case_ratio(msg):
    """Accepts a twitter message (or used with .apply(lambda x:)).
    Returns the ratio of capitalized characters out of the total number of characters.

    EX:
    df['case_ratio'] = df['text'].apply(lambda x: case_ratio(x))"""
    import numpy as np
    msg_length = len(msg)
    test_upper = [(1) for x in msg if x.isupper()]
    test_lower = [(1) for x in msg if x.islower()]
    test_ratio = np.round(sum(test_upper) / msg_length, 5)
    return test_ratio


@classmethod
def prolog_query(cls, query):
    """Run prolog query without specifying trial"""
    cls.init_cli()
    id_to_instance = {}
    cache = set()
    no_cache = set()
    for inst in cls.get_instances():
        id_to_instance[inst.trial.id] = inst
        (cache if inst.use_cache else no_cache).add(inst.trial.id)
    retract_ids = no_cache - cache
    for tid in retract_ids:
        id_to_instance[tid].retract()
    return cls.prolog_cli.query(query)


def get_bucket_tagging(Bucket=None):
    """
    Returns the tag set associated with the bucket.
    See also: AWS API Documentation

    :example: response = client.get_bucket_tagging(
        Bucket='string'
    )

    :type Bucket: string
    :param Bucket: [REQUIRED]

    :rtype: dict
    :return: {
        'TagSet': [
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    }

    """
    pass


@classmethod
def update(cls, key, value, accumulator):
    """ Update the accumulator for the period. For updating only the key,
        override update_key instead.
        """
    accumulator[key] = cls.update_key(value, accumulator[key])
    return accumulator


def breakCentroidTie(attribute_variants, min_dist_indices):
    """
    Finds centroid when there are multiple values w/ min avg distance
    (e.g. any dupe cluster of 2) right now this selects the first
    among a set of ties, but can be modified to break ties in strings
    by selecting the longest string

    """
    return attribute_variants[min_dist_indices[0]]


def get_byte_array(integer):
    """Return the variable length bytes corresponding to the given int"""
    return int.to_bytes(integer, (integer.bit_length() + 8 - 1) // 8,
        byteorder='big', signed=False)


@classmethod
def extract_polygons(cls, obj):
    """
        Extract a list of polygons from given object
        """
    return obj.findall('.//{{{}}}Polygon'.format(cls.gml))


def set_solution_scale(distance: float=0.0):
    """Set object solution scale using distance between two selected tracks

    :param distance: Distance, Distance between selected tracks
    :type distance: float
    """
    pass


def gen_cmake_command(config):
    """
    Generate CMake command.
    """
    from autocmake.extract import extract_list
    s = []
    s.append('\n\ndef gen_cmake_command(options, arguments):')
    s.append('    """')
    s.append('    Generate CMake command based on options and arguments.')
    s.append('    """')
    s.append('    command = []')
    for env in config['export']:
        s.append('    command.append({0})'.format(env))
    s.append("    command.append(arguments['--cmake-executable'])")
    for definition in config['define']:
        s.append('    command.append({0})'.format(definition))
    s.append(
        "    command.append('-DCMAKE_BUILD_TYPE={0}'.format(arguments['--type']))"
        )
    s.append(
        '    command.append(\'-G"{0}"\'.format(arguments[\'--generator\']))')
    s.append('    if arguments[\'--cmake-options\'] != "\'\'":')
    s.append("        command.append(arguments['--cmake-options'])")
    s.append("    if arguments['--prefix']:")
    s.append(
        '        command.append(\'-DCMAKE_INSTALL_PREFIX="{0}"\'.format(arguments[\'--prefix\']))'
        )
    s.append("""
    return ' '.join(command)""")
    return '\n'.join(s)


def _add_codes(inv):
    """ add network, station, location, channel codes where applicable """
    for network in inv:
        net_code = network.code
        network.network_code = net_code
        for station in network:
            sta_code = station.code
            station.station_code = sta_code
            station.network_code = net_code
            for channel in station:
                channel.station_code = sta_code
                channel.network_code = net_code
                channel.channel_code = channel.code


def search_threads(threads, keyword=None):
    """Match deal title and dealer names with keyword specified."""
    if keyword is None:
        return
    keyword = str(keyword)
    for deal in threads:
        if keyword.lower() in deal.title.lower(
            ) or deal.dealer_name and keyword.lower(
            ) in deal.dealer_name.lower():
            yield deal


def isstdiofilename(pat):
    """True if the given pat looks like a filename denoting stdin/stdout"""
    return not pat or pat == b'-'


def set_URL_scheme_handler(url_scheme, bundle_identifier):
    """Set handler for given URL scheme."""
    return


def pass_return(func, **ctx):
    """Get the return from context and pass to given callable."""
    return func(ctx['x_return'])


def _printVersion(name):
    """Prints the current FSLeyes version.

    :arg name: Name of the tool (probably either ``fsleyes`` or ``render``).
    """
    from . import version
    print('{}/FSLeyes version {}'.format(name, version.__version__))


def avg_w2v_semantic_similarity(docs, N):
    """Compute average semantic similarity between adjacent sentences.

    This is using word2vec :cite:`mikolov2013word2vec` model based on SPACY
    implementation. The semantic similarity is based on
    :cite:`foltz1998measurement` approach to compute text coherence.

    :param docs: Docs generator provided by SPACY API
    :type docs: Doc Generator
    :param N: Number of sentences
    :type N: int
    :return: Average sentence similarity (cosine)
    :rtype: float
    """
    if N <= 1:
        raise RuntimeError('N of sentences should be > 1, {} was provided'.
            format(N))
    avg_sim = 0
    prev_doc = next(docs)
    done = False
    while not done:
        try:
            curr_doc = next(docs)
            avg_sim += prev_doc.similarity(curr_doc)
            prev_doc = curr_doc
        except StopIteration:
            done = True
    return avg_sim / float(N - 1)


def get_local_ip(ifname='eth0'):
    """
        prefix = enp2s0  or eth0
    :param ifname:
    :return:
    """
    import socket, fcntl, struct
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 35093, struct.pack(
        '256s', bytes(ifname[:15], 'utf-8')))[20:24])


@classmethod
def likes(cls, target):
    """ Check if this bumper likes the target. """
    raise NotImplementedError


def klein_stl(face_dicts):
    """ Yield triangles describing these faces. """
    for face in face_dicts:
        vertices = face['vertices']
        for i in range(len(vertices) - 2):
            yield vertices[0], vertices[i + 1], vertices[i + 2]
    return


@classmethod
def resolve_connection(cls, connection=None):
    """
        Resolve a connection instance.

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

        :rtype: orator.connections.Connection
        """
    return cls.__resolver.connection(connection)


def area(poly):
    """Find the area of a given polygon using the shoelace algorithm.

    Parameters
    ----------
    poly: (2, N) ndarray
        2-dimensional coordinates representing an ordered
        traversal around the edge a polygon.

    Returns
    -------
    area: float

    """
    a = 0.0
    n = len(poly)
    for i in range(n):
        a += poly[i][0] * poly[(i + 1) % n][1] - poly[(i + 1) % n][0] * poly[i
            ][1]
    return abs(a) / 2.0


@classmethod
def subscription_path(cls, project, subscription):
    """Returns a fully-qualified subscription resource name string."""
    return cls._SUBSCRIPTION_PATH_TEMPLATE.render({'project': project,
        'subscription': subscription})


@staticmethod
def p_axis_pts_optional(p):
    """axis_pts_optional : display_identifier
                             | read_only
                             | format
                             | deposit
                             | byte_order
                             | function_list
                             | ref_memory_segment
                             | guard_rails
                             | extended_limits
                             | annotation
                             | if_data_axis_pts
                             | calibration_access
                             | ecu_address_extension"""
    p[0] = p.slice[1].type, p[1]


def print_more_help():
    """ Prints help message """
    help_text = """
    --------------------------------------------------------------------------------------------------------
    Passwords are not encrypted. The "devicetype" field for a device must match a device type from netmiko.
    Netmiko library information is here. https://github.com/ktbyers/netmiko
    IP addresses must be unique. There should not be two devices in the database with the same management IP.
    Last seen value is updated whenever a connection is made to a device to update version or config
    information that is stored in the database.

    Database configuration for the sqlite database.
    sqlite> pragma table_info(devices);
    0|ip|text|1||0
    1|hostname|text|0||0
    2|description|text|0||0
    3|building|text|0||0
    4|location|text|0||0
    5|username|text|1||0
    6|password|text|1||0
    7|device_type|text|1||0
    8|last_seen|text|0||0
    9|version_info|text|0||0
    10|running_config|text|0||0

    """
    return help_text


def commonancestorsheads(node1, node2):
    """Obtain an iterable of nodes containing heads of common ancestors.

        See ``ancestor.commonancestorsheads()``.
        """


def begin_contour():
    """
	Use the beginContour() and endContour() functions
	to create negative shapes within shapes such as
	the center of the letter 'O'. beginContour() begins
	recording vertices for the shape and endContour() stops
	recording. The vertices that define a negative shape must
	"wind" in the opposite direction from the exterior shape.
	First draw vertices for the exterior clockwise order, then
	for internal shapes, draw vertices shape in counter-clockwise.

	"""
    global is_contour, contour_vertices, contour_vertices_types
    is_contour = True
    contour_vertices = []
    contour_vertices_types = []


@classmethod
def getTimezone(cls):
    """Returns the pytz timezone for the market session."""
    return cls.timezone


def add_to_class(cls, name, value):
    """Add an attribute to this class.

        If the value defines a `contribute_to_class` method, it will be run
        with this class and the given name as its arguments.
        """
    if hasattr(value, 'contribute_to_class'):
        value.contribute_to_class(cls, name)
    else:
        setattr(cls, name, value)


def _replace_llvm_memset_declaration(m):
    """Replace `llvm.memset` declaration for llvm7+.

    Used as functor for `re.sub.
    """
    params = list(m.group(1).split(','))
    params.insert(-1, 'i32')
    out = ', '.join(params)
    return '({})'.format(out)


def import_module(dotted_path):
    """
    Imports the specified module based on the
    dot notated import path for the module.
    """
    import importlib
    module_parts = dotted_path.split('.')
    module_path = '.'.join(module_parts[:-1])
    module = importlib.import_module(module_path)
    return getattr(module, module_parts[-1])


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

        :param AppUnlinkTeamDetails val:
        :rtype: EventDetails
        """
    return cls('app_unlink_team_details', val)


def ghost_curves_create():
    """Create snapshot (Ghosts) of selected F-Curves as background aid for active Graph Editor

    """
    pass


def flat_value(value, sep='|'):
    """
    Flattens values that may be lists.
    """
    if isinstance(value, list):
        return sep.join(value)
    else:
        return str(value)


def lcs2(X, Y, equal):
    """
    apply the greedy lcs/ses algorithm between X and Y sequence
    (should be any Python's sequence)
    equal is a function to compare X and Y which must return 0 if
    X and Y are different, 1 if they are identical
    return a list of matched pairs in tuplesthe greedy lcs/ses algorithm
    """
    N, M = len(X), len(Y)
    if not X or not Y:
        return []
    max = N + M
    v = [(0) for i in range(2 * max + 1)]
    common = [[] for i in range(2 * max + 1)]
    for D in range(max + 1):
        for k in range(-D, D + 1, 2):
            if k == -D or k != D and v[k - 1] < v[k + 1]:
                x = v[k + 1]
                common[k] = common[k + 1][:]
            else:
                x = v[k - 1] + 1
                common[k] = common[k - 1][:]
            y = x - k
            while x < N and y < M and equal(X[x], Y[y]):
                common[k].append((x, y))
                x += 1
                y += 1
            v[k] = x
            if x >= N and y >= M:
                return [(X[x], Y[y]) for x, y in common[k]]


def reset():
    """Discards all queued messages."""


def reload(adjust_length: bool=False):
    """Reload strips in the sequencer

    :param adjust_length: Adjust Length, Adjust length of strips to their data length
    :type adjust_length: bool
    """
    pass


def func_default_for(cls, key):
    """Decorator to define a functional default for a given key."""
    return lambda function: [cls.register_func_default(key, function), function
        ][1]


def parsing_set_single_offsset(response, tips=False):
    """
    功能：解析设置单舵机偏移值的回应信息
    输入：
    response：机器人返回的设置单舵机偏移值的回应信息
    返回：
    success:判定是否设置成功。数据格式bool
    """
    if response == b'':
        print('回应内容为空，请重新获取回应！')
        return
    success = True
    cmd_len = response[2]
    cmd_type = response[3]
    if cmd_type != 38:
        print('解析类型错误，请检查回应内容，当前命令类型为%d' % cmd_type)
        return 0
    joint_id = response[4]
    feedback = response[5]
    if feedback != 0:
        success = False
        if feedback == 1:
            print('错误：%d号舵机的id值错误！' % joint_id)
        elif feedback == 2:
            print('错误：%d号舵机没有应答！' % joint_id)
    if tips:
        ss = '成功' if success else '失败'
        print('设置单舵机偏移值命令执行%s！' % ss)
    return success


@staticmethod
def getJavaPackage():
    """ Returns package name String. """
    return 'com.microsoft.ml.spark.nn.KNNModel'


@classmethod
def policy_is_required(cls, pcluster_config):
    """Describe whether the policy represented by this class must be included."""
    return pcluster_config.get_section('cluster').get_param_value('scheduler'
        ) == 'awsbatch'


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


def get_supported_interfaces(handler_input):
    """Retrieves the supported interfaces from input request.

    The method returns an
    :py:class:`ask_sdk_model.supported_interfaces.SupportedInterfaces`
    object instance listing each interface that the device
    supports. For example, if ``supported_interfaces`` includes
    ``audio_player``, then you know that the device supports streaming
    audio using the AudioPlayer interface. More information on
    `supportedInterfaces` can be found here :
    https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#system-object

    :param handler_input: The handler input instance that is generally
        passed in the sdk's request and exception components
    :type handler_input: ask_sdk_core.handler_input.HandlerInput
    :return: Instance of
        :py:class:`ask_sdk_model.supported_interfaces.SupportedInterfaces`
        mentioning which all interfaces the device supports
    :rtype: ask_sdk_model.supported_interfaces.SupportedInterfaces
    """
    return (handler_input.request_envelope.context.system.device.
        supported_interfaces)


def memberships_pending_warning():
    """Memberships that have been disabled due to excessive bounces and require a
        warning to be sent.

        The total number of warnings sent to these are less than the
        MailingList's configured number of warnings to be sent before the
        membership is removed.
        """


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


def update_status(apps, schema_editor):
    """
    Updates the status of the ingredients
    """
    Ingredient = apps.get_model('nutrition', 'Ingredient')
    Ingredient.objects.filter(status__in=('5', '4')).update(status=2)


def __saveShortcut(act, category, prefClass):
    """
    Private function to write a single keyboard shortcut to the settings.

    @param act reference to the action object (E5Action)
    @param category category the action belongs to (string)
    @param prefClass preferences class used as the storage area
    """
    if act.objectName():
        prefClass.settings.setValue('Shortcuts/{0}/{1}/Accel'.format(
            category, act.objectName()), act.shortcut().toString())
        prefClass.settings.setValue('Shortcuts/{0}/{1}/AltAccel'.format(
            category, act.objectName()), act.alternateShortcut().toString())


def overlapping_in_bed(fname, r_chr, r_start, r_stop):
    """
    Get from a bed all intervals that overlap the region defined by
    r_chr, r_start, r_stop.
    """
    rval = []
    for line in open(fname):
        if line.startswith('#') or line.startswith('track'):
            continue
        fields = line.split()
        chr, start, stop = fields[0], int(fields[1]), int(fields[2])
        if chr == r_chr and start < r_stop and stop >= r_start:
            rval.append((chr, max(start, r_start), min(stop, r_stop)))
    return rval


@staticmethod
def build_image_path(chapter_dir, manga, chapter, image):
    """Build the image path based.

        Parameters
        ----------
        chapter_dir : str
            the manga dir path
        manga : str
            the manga name
        chapter : str
            the chapter number
        image : str
            the image name

        Returns
        -------
        str
            the full image path
        """
    image_name = '{0}-{1}-{2}.jpg'.format(manga, chapter, image)
    image_path = '/'.join([chapter_dir, image_name])
    return image_path


def l1_dissimilarity(a, b):
    """Compute dissimilarity between rows of  `a` and `b` as :math:`||a-b||_1`.

    """
    assert len(a.shape) == len(b.shape)
    return (a - b).norm(p=1, dim=-1)


def insertion_sort(nums):
    """
    returns sorted list
    """
    for i in range(1, len(nums)):
        value = nums[i]
        for j in range(i - 1, -1, -1):
            if nums[j] > value:
                nums[j + 1] = nums[j]
            else:
                break
        nums[j] = value
    return nums


def p_statement(p):
    """
    statement : OFFSET PLAIN_STATEMENT
    statement : BYTE_ORDER
    """
    if len(p) == 2:
        p[0] = None, p[1]
    else:
        p[0] = p[1], p[2]


def zeros_like(data=None, out=None, name=None, **kwargs):
    """Return an array of zeros with the same shape, type and storage type
    as the input array.

    The storage type of ``zeros_like`` output depends on the storage type of the input

    - zeros_like(row_sparse) = row_sparse
    - zeros_like(csr) = csr
    - zeros_like(default) = default

    Examples::

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

      zeros_like(x) = [[ 0.,  0.,  0.],
                       [ 0.,  0.,  0.]]

    Parameters
    ----------
    data : NDArray
        The input

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

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


def put_scaling_policy(PolicyName=None, ServiceNamespace=None, ResourceId=
    None, ScalableDimension=None, PolicyType=None,
    StepScalingPolicyConfiguration=None):
    """
    Creates or updates a policy for an Application Auto Scaling scalable target.
    Each scalable target is identified by a service namespace, resource ID, and scalable dimension. A scaling policy applies to the scalable target identified by those three attributes. You cannot create a scaling policy without first registering a scalable target using  RegisterScalableTarget .
    To update a policy, specify its policy name and the parameters that you want to change. Any parameters that you don't specify are not changed by this update request.
    You can view the scaling policies for a service namespace using  DescribeScalingPolicies . If you are no longer using a scaling policy, you can delete it using  DeleteScalingPolicy .
    See also: AWS API Documentation

    Examples
    This example applies a scaling policy to an Amazon ECS service called web-app in the default cluster. The policy increases the desired count of the service by 200%, with a cool down period of 60 seconds.
    Expected Output:
    This example applies a scaling policy to an Amazon EC2 Spot fleet. The policy increases the target capacity of the spot fleet by 200%, with a cool down period of 180 seconds.",
    Expected Output:

    :example: response = client.put_scaling_policy(
        PolicyName='string',
        ServiceNamespace='ecs'|'elasticmapreduce'|'ec2'|'appstream',
        ResourceId='string',
        ScalableDimension='ecs:service:DesiredCount'|'ec2:spot-fleet-request:TargetCapacity'|'elasticmapreduce:instancegroup:InstanceCount'|'appstream:fleet:DesiredCapacity',
        PolicyType='StepScaling',
        StepScalingPolicyConfiguration={
            'AdjustmentType': 'ChangeInCapacity'|'PercentChangeInCapacity'|'ExactCapacity',
            'StepAdjustments': [
                {
                    'MetricIntervalLowerBound': 123.0,
                    'MetricIntervalUpperBound': 123.0,
                    'ScalingAdjustment': 123
                },
            ],
            'MinAdjustmentMagnitude': 123,
            'Cooldown': 123,
            'MetricAggregationType': 'Average'|'Minimum'|'Maximum'
        }
    )

    :type PolicyName: string
    :param PolicyName: [REQUIRED]
            The name of the scaling policy.

    :type ServiceNamespace: string
    :param ServiceNamespace: [REQUIRED]
            The namespace of the AWS service. For more information, see AWS Service Namespaces in the Amazon Web Services General Reference .

    :type ResourceId: string
    :param ResourceId: [REQUIRED]
            The identifier of the resource associated with the scaling policy. This string consists of the resource type and unique identifier.
            ECS service - The resource type is service and the unique identifier is the cluster name and service name. Example: service/default/sample-webapp .
            Spot fleet request - The resource type is spot-fleet-request and the unique identifier is the Spot fleet request ID. Example: spot-fleet-request/sfr-73fbd2ce-aa30-494c-8788-1cee4EXAMPLE .
            EMR cluster - The resource type is instancegroup and the unique identifier is the cluster ID and instance group ID. Example: instancegroup/j-2EEZNYKUA1NTV/ig-1791Y4E1L8YI0 .
            AppStream 2.0 fleet - The resource type is fleet and the unique identifier is the fleet name. Example: fleet/sample-fleet .

    :type ScalableDimension: string
    :param ScalableDimension: [REQUIRED]
            The scalable dimension. This string consists of the service namespace, resource type, and scaling property.
            ecs:service:DesiredCount - The desired task count of an ECS service.
            ec2:spot-fleet-request:TargetCapacity - The target capacity of a Spot fleet request.
            elasticmapreduce:instancegroup:InstanceCount - The instance count of an EMR Instance Group.
            appstream:fleet:DesiredCapacity - The desired capacity of an AppStream 2.0 fleet.

    :type PolicyType: string
    :param PolicyType: The policy type. If you are creating a new policy, this parameter is required. If you are updating a policy, this parameter is not required.

    :type StepScalingPolicyConfiguration: dict
    :param StepScalingPolicyConfiguration: The configuration for the step scaling policy. If you are creating a new policy, this parameter is required. If you are updating a policy, this parameter is not required. For more information, see StepScalingPolicyConfiguration and StepAdjustment .
            AdjustmentType (string) --The adjustment type, which specifies how the ScalingAdjustment parameter in a StepAdjustment is interpreted.
            StepAdjustments (list) --A set of adjustments that enable you to scale based on the size of the alarm breach.
            (dict) --Represents a step adjustment for a StepScalingPolicyConfiguration . Describes an adjustment based on the difference between the value of the aggregated CloudWatch metric and the breach threshold that you've defined for the alarm.
            For the following examples, suppose that you have an alarm with a breach threshold of 50:
            To trigger the adjustment when the metric is greater than or equal to 50 and less than 60, specify a lower bound of 0 and an upper bound of 10.
            To trigger the adjustment when the metric is greater than 40 and less than or equal to 50, specify a lower bound of -10 and an upper bound of 0.
            There are a few rules for the step adjustments for your step policy:
            The ranges of your step adjustments can't overlap or have a gap.
            At most one step adjustment can have a null lower bound. If one step adjustment has a negative lower bound, then there must be a step adjustment with a null lower bound.
            At most one step adjustment can have a null upper bound. If one step adjustment has a positive upper bound, then there must be a step adjustment with a null upper bound.
            The upper and lower bound can't be null in the same step adjustment.
            MetricIntervalLowerBound (float) --The lower bound for the difference between the alarm threshold and the CloudWatch metric. If the metric value is above the breach threshold, the lower bound is inclusive (the metric must be greater than or equal to the threshold plus the lower bound). Otherwise, it is exclusive (the metric must be greater than the threshold plus the lower bound). A null value indicates negative infinity.
            MetricIntervalUpperBound (float) --The upper bound for the difference between the alarm threshold and the CloudWatch metric. If the metric value is above the breach threshold, the upper bound is exclusive (the metric must be less than the threshold plus the upper bound). Otherwise, it is inclusive (the metric must be less than or equal to the threshold plus the upper bound). A null value indicates positive infinity.
            The upper bound must be greater than the lower bound.
            ScalingAdjustment (integer) -- [REQUIRED]The amount by which to scale, based on the specified adjustment type. A positive value adds to the current scalable dimension while a negative number removes from the current scalable dimension.

            MinAdjustmentMagnitude (integer) --The minimum number to adjust your scalable dimension as a result of a scaling activity. If the adjustment type is PercentChangeInCapacity , the scaling policy changes the scalable dimension of the scalable target by this amount.
            Cooldown (integer) --The amount of time, in seconds, after a scaling activity completes where previous trigger-related scaling activities can influence future scaling events.
            For scale out policies, while Cooldown is in effect, the capacity that has been added by the previous scale out event that initiated the Cooldown is calculated as part of the desired capacity for the next scale out. The intention is to continuously (but not excessively) scale out. For example, an alarm triggers a step scaling policy to scale out an Amazon ECS service by 2 tasks, the scaling activity completes successfully, and a Cooldown period of 5 minutes starts. During the Cooldown period, if the alarm triggers the same policy again but at a more aggressive step adjustment to scale out the service by 3 tasks, the 2 tasks that were added in the previous scale out event are considered part of that capacity and only 1 additional task is added to the desired count.
            For scale in policies, the Cooldown period is used to block subsequent scale in requests until it has expired. The intention is to scale in conservatively to protect your application's availability. However, if another alarm triggers a scale out policy during the Cooldown period after a scale-in, Application Auto Scaling scales out your scalable target immediately.
            MetricAggregationType (string) --The aggregation type for the CloudWatch metrics. Valid values are Minimum , Maximum , and Average .

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

    """
    pass


@classmethod
def from_trace(cls, trace, n_stacks=1, delay=0):
    """Initialize a `TimeSeries` object from a trace object.

        This method is more general method than `from_trace_seg2`,
        as it does not attempt to extract any metadata from the `Trace`
        object.

        Parameters
        ----------
        trace : Trace
            Refer to
            `obspy documentation <https://github.com/obspy/obspy/wiki>`_
            for more information

        n_stacks : int, optional
            Number of stacks the time series represents, (default is
            1, signifying a single unstacked time record).

        delay : float {<=0.}, optional
            Denotes the pre-event delay, (default is zero,
            meaning no pre-event noise was recorded).

        Returns
        -------
        TimeSeries
            Initialized with information from `trace`.
        """
    return cls(amplitude=trace.data, dt=trace.stats.delta, n_stacks=
        n_stacks, delay=delay)


def AddInstanceTags(r, instance, tags, dry_run=False):
    """
    Adds tags to an instance.

    @type instance: str
    @param instance: instance to add tags to
    @type tags: list of str
    @param tags: tags to add to the instance
    @type dry_run: bool
    @param dry_run: whether to perform a dry run

    @rtype: int
    @return: job id
    """
    query = {'tag': tags, 'dry-run': dry_run}
    return r.request('put', '/2/instances/%s/tags' % instance, query=query)


def trace_realign_result(row, realign_cigar):
    """
    The function is used to trace the cigar index of introns which are used to split the realign_cigar.
    Return a ci_list.
    realn_tx_pos means the position regardless of introns and relative to the realign_start. The position of
    bases on the tx_seq.
    """
    ci_list = []
    intron_start = row['tx_leftexon_end']
    realn_tx_pos = row['tx_leftexon_end'] - row['realign_start']
    realn_intron_pos = [realn_tx_pos]
    for exon_size in row['exon_sizes']:
        realn_tx_pos += exon_size
        realn_intron_pos.append(realn_tx_pos)
    for realn_tx_pos in realn_intron_pos:
        trace = realign_cigar.trace_ci_rdp(start_ci=(0, 0), start_pos=0,
            end_pos=realn_tx_pos, start_rdp=0)
        if not trace[2]:
            raise Exception(
                'Error:, cannot trace to the intron position in the realign cigar!'
                )
        ci_list.append(trace[0])
    return ci_list


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

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


def _setOpt(name, value, conv=None):
    """set a module level value from environ/default"""
    from os import environ
    ename = 'RL_' + name
    if ename in environ:
        value = environ[ename]
    if conv:
        value = conv(value)
    globals()[name] = value


def get_trip_headsign(data, service_ref):
    """Parse trip headsign based on service reference id"""
    service = data.TransXChange.Services.Service
    if service.ServiceCode == service_ref:
        return service.Description.cdata
    else:
        raise ValueError('Could not find trip headsign for', service_ref)


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


def is_included_in(i1, i2):
    """ Is the interval included in i1?
        """
    return i2.inf <= i1.inf and i1.sup <= i2.sup


def get_token_and_platform_from_alias(pushbots, alias):
    """
    Gets the tokens from alias. You can modify this to get
    tokens based on any info. Note that multiple devices,
    may have the same alias, so we return them all.
    """
    devices = []
    code, content = pushbots.devices_info_all()
    if code != 200:
        print('Something went wrong:{0}'.format(content))
        return
    for json in content:
        try:
            if json['alias'] == alias:
                devices.append((json['token'], json['platform']))
        except KeyError:
            pass
    return devices


def float_or_x(x):
    """Tries to convert to float, returns x if it can't"""
    try:
        return float(x)
    except:
        return x


def lower_first(s):
    """Lower case the first character of a string."""
    return s[:1].lower() + s[1:]


@classmethod
def wrap(cls, models, build=True, handler=None, **kwargs):
    """
        "Wraps" the provided sequence (or single set) of model based data into a
        sequence of models (or a single model) so that proper business logic may
        be used for operations on top of that data.

        In case the extra handler argument is passed it's going to be called for
        each model that is going to be "wrapped" allowing an extra "layer" for
        the transformation of the model.

        The additional named arguments parameters allows extensibility to set
        extra value in the creation of the wrapped object.

        This operation is specially useful for API based environments where client
        side business logic is meant to be added to the static data.

        :type models: List
        :param models: Sequence (or single) set of models that are going to be wrapped
        around instances of the current class.
        :type build: bool
        :param build: If the "custom" build operation should be performed after
        the wrap operation is performed so that new custom attributes may be
        injected into the resulting instance.
        :type handler: Function
        :param handler: Handler function that is going to be called for each of the
        models after the build process has been performed, allows an extra transform
        operation to be performed at runtime.
        :rtype: List
        :return: The sequence of models (or single model) representing the provided
        set of dictionary models that were sent as arguments.
        """
    is_sequence = isinstance(models, (list, tuple))
    if not is_sequence:
        models = [models]
    wrapping = []
    for model in models:
        if not isinstance(model, dict):
            continue
        _model = cls(model=model, **kwargs)
        handler and handler(_model.model)
        build and cls.build(_model.model, map=False)
        wrapping.append(_model)
    if is_sequence:
        return wrapping
    else:
        return wrapping[0] if wrapping else None


def merge_developer_identities(SourceUserIdentifier=None,
    DestinationUserIdentifier=None, DeveloperProviderName=None,
    IdentityPoolId=None):
    """
    Merges two users having different IdentityId s, existing in the same identity pool, and identified by the same developer provider. You can use this action to request that discrete users be merged and identified as a single user in the Cognito environment. Cognito associates the given source user (SourceUserIdentifier ) with the IdentityId of the DestinationUserIdentifier . Only developer-authenticated users can be merged. If the users to be merged are associated with the same public provider, but as two different users, an exception will be thrown.
    You must use AWS Developer credentials to call this API.
    See also: AWS API Documentation

    :example: response = client.merge_developer_identities(
        SourceUserIdentifier='string',
        DestinationUserIdentifier='string',
        DeveloperProviderName='string',
        IdentityPoolId='string'
    )

    :type SourceUserIdentifier: string
    :param SourceUserIdentifier: [REQUIRED]
            User identifier for the source user. The value should be a DeveloperUserIdentifier .

    :type DestinationUserIdentifier: string
    :param DestinationUserIdentifier: [REQUIRED]
            User identifier for the destination user. The value should be a DeveloperUserIdentifier .

    :type DeveloperProviderName: string
    :param DeveloperProviderName: [REQUIRED]
            The 'domain' by which Cognito will refer to your users. This is a (pseudo) domain name that you provide while creating an identity pool. This name acts as a placeholder that allows your backend and the Cognito service to communicate about the developer provider. For the DeveloperProviderName , you can use letters as well as period (.), underscore (_), and dash (-).

    :type IdentityPoolId: string
    :param IdentityPoolId: [REQUIRED]
            An identity pool ID in the format REGION:GUID.

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

    """
    pass


def dequote(string):
    """ Removes quotes from around a string """
    if string.startswith('"') and string.endswith('"') or string.startswith("'"
        ) and string.endswith("'"):
        return string[1:-1]
    else:
        return string


def associate_subnet_cidr_block(SubnetId=None, Ipv6CidrBlock=None):
    """
    Associates a CIDR block with your subnet. You can only associate a single IPv6 CIDR block with your subnet. An IPv6 CIDR block must have a prefix length of /64.
    See also: AWS API Documentation

    :example: response = client.associate_subnet_cidr_block(
        SubnetId='string',
        Ipv6CidrBlock='string'
    )

    :type SubnetId: string
    :param SubnetId: [REQUIRED]
            The ID of your subnet.

    :type Ipv6CidrBlock: string
    :param Ipv6CidrBlock: [REQUIRED]
            The IPv6 CIDR block for your subnet. The subnet must have a /64 prefix length.

    :rtype: dict
    :return: {
        'SubnetId': 'string',
        'Ipv6CidrBlockAssociation': {
            'Ipv6CidrBlock': 'string',
            'Ipv6CidrBlockState': {
                'State': 'associating'|'associated'|'disassociating'|'disassociated'|'failing'|'failed',
                'StatusMessage': 'string'
            },
            'AssociationId': 'string'
        }
    }

    """
    pass


@staticmethod
def _invoke(thing, caller=None):
    """
        invoke method on object but return object instead of call result if the
        call returns None

        @param thing: some thing
        @param caller: a callable (default: None)
        """
    results = caller(thing)
    return thing if results is None else results


def V_d2bV_by_V_Approx(V):
    """
    Approximate V*d^2(bV)/dV^2 for single mode fiber.

    This value is needed to determine the waveguide dispersion.  This
    approximation is for the fundamental mode in the fiber and is good
    to 1% when 1.4<V<2.4.  Approximation by Marcuse (1979)

    Args:
        V:      V-parameter of the fiber     [--]
    Returns:
        V*d^2(bV)/dV^2                       [--]
    """
    return 0.08 + 0.549 * (2.834 - V) ** 2


@classmethod
def load_state_dict(cls, state_dict):
    """ Construct a MultiVocab by reading from a state dict."""
    raise NotImplementedError


def get_unreachable_nodes(ircfg, edges_to_del, heads):
    """
    Return the unreachable nodes starting from heads and the associated edges to
    be deleted.

    @ircfg: IRCFG instance
    @edges_to_del: edges already marked as deleted
    heads: locations of graph heads
    """
    todo = set(heads)
    visited_nodes = set()
    new_edges_to_del = set()
    while todo:
        node = todo.pop()
        if node in visited_nodes:
            continue
        visited_nodes.add(node)
        for successor in ircfg.successors(node):
            if (node, successor) not in edges_to_del:
                todo.add(successor)
    all_nodes = set(ircfg.nodes())
    nodes_to_del = all_nodes.difference(visited_nodes)
    for node in nodes_to_del:
        for successor in ircfg.successors(node):
            if successor not in nodes_to_del:
                new_edges_to_del.add((node, successor))
    return nodes_to_del, new_edges_to_del


def filter_transcript(gene_dict, transcript_dict):
    """
	For each coding gene, only one principal transcript is selected for meta-analysis
	"""
    filter_tids = []
    for gobj in gene_dict.values():
        if gobj.chrom in ('chrM', 'chrMT', 'M', 'MT'):
            continue
        select_tid = None
        if gobj.principal_transcripts:
            if len(gobj.principal_transcripts) == 1:
                tid = gobj.principal_transcripts[0]
                if transcript_dict[tid].startcodon and transcript_dict[tid
                    ].stopcodon:
                    select_tid = tid
            else:
                for tid in gobj.principal_transcripts:
                    if transcript_dict[tid].startcodon and transcript_dict[tid
                        ].stopcodon:
                        if select_tid:
                            if transcript_dict[tid].length > transcript_dict[
                                select_tid].length:
                                select_tid = tid
                        else:
                            select_tid = tid
        elif gobj.transcripts:
            levels = set([transcript_dict[tid].attr.get('level', None) for
                tid in gobj.transcripts])
            if len(levels) > 1:
                level = list(sorted(levels))[0]
            else:
                level = list(levels)[0]
            for tid in gobj.transcripts:
                if transcript_dict[tid].attr.get('level', None):
                    if transcript_dict[tid].attr['level'] == level:
                        if transcript_dict[tid].startcodon and transcript_dict[
                            tid].stopcodon:
                            if select_tid:
                                if transcript_dict[tid
                                    ].length > transcript_dict[select_tid
                                    ].length:
                                    select_tid = tid
                            else:
                                select_tid = tid
                elif transcript_dict[tid].startcodon and transcript_dict[tid
                    ].stopcodon:
                    if select_tid:
                        if transcript_dict[tid].length > transcript_dict[
                            select_tid].length:
                            select_tid = tid
                    else:
                        select_tid = tid
        if select_tid:
            filter_tids.append(select_tid)
    return set(filter_tids)


@classmethod
def all_formats(cls):
    """Mapping of all defined log format patterns.

        :returns: dictionary of name:``LogFormat`` instances.
        :rtype: ``dict``

        """
    formats = {}
    for name, ref in cls.__formats_.items():
        instance = ref()
        if instance is not None:
            formats[name] = instance
    return formats


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

        :param SharedFolderMetadata val:
        :rtype: ShareFolderLaunch
        """
    return cls('complete', val)


def check_response(response):
    """Check if a response is success according to status_code"""
    if response and response.status_code == 200:
        return True
    return False


def export_to_pandas(pipe, dst, **kwargs):
    """
    Basic example how to export into Pandas DataFrame
    Custom params for "read_csv" may be passed in **kwargs
    """
    import pandas
    return pandas.read_csv(pipe, skip_blank_lines=False, **kwargs)


def getTagsForContext(include_hidden=False):
    """Return the tags for the context"""


@staticmethod
def to_html(pio, personaliseResultWrapper):
    """ Renders results to an HTML table, fundamentally flawed at this point as there is no support for blends with more then 2 models"""
    html = '
Results for group {label}
'.format(label=
        personaliseResultWrapper.experiment['abvariant']['label'])
    html += '
'
    html += (
        '
model1.name	model1.weight	model1.score	model2.name	model2.weight	model2.score	wscore	value
'
        )
    for res in personaliseResultWrapper._results:
        html += '
'
        if len(res.components) == 0:
            html += (
                '						{score}	{url}	'
                .format(score=res.fscore, url=res.target['value']['url']))
        elif len(res.components) == 1:
            html += (
                '{0}	{1}	{2:.2f}				{3}	{4}	'
                .format(res.components[0]['model']['name'], res.components[
                0]['weight'], res.components[0]['cscore'], res.fscore, res.
                target['value']['url']))
        elif len(res.components) == 2:
            html += (
                '{0}	{1}	{2:.2f}	{3}	{4}	{5:.2f}	{6}	{7}	'
                .format(res.components[0]['model']['name'], res.components[
                0]['weight'], res.components[0]['cscore'], res.components[1
                ]['model']['name'], res.components[1]['weight'], res.
                components[1]['cscore'], res.fscore, res.target['value'][
                'url']))
        else:
            print(
                "we don't support to_html() for results of blends with more then two models"
                )
            pass
        html += '
'
    return html


def metric_inc(key, value=1):
    """Increments the specified metric key value by the specified value.

    :param str|unicode key:

    :param int value:

    :rtype: bool
    """
    return False


def is_album_id(item_id):
    """Validate if ID is in the format of a Google Music album ID."""
    return len(item_id) == 27 and item_id.startswith('B')


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 match_items(lines, content_old):
    """Create items for mangled lines.

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

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

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

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

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

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


def default_config_filename(installer):
    """
    This function can return a default filename or directory for the
    configuration file, if none was explicitly given.

    Return None to mean no preference.  The first non-None returning
    value will be used.

    Pay attention to ``installer.expect_config_directory`` here,
    and to ``installer.default_config_filename``.
    """
    return installer.default_config_filename


def remove_comment(string_entry):
    """
    Takes a single line and removes and .ini type comments.
    Also remove any spaces at the begining or end of a commented line
    """
    result = string_entry
    for c in '#;':
        if c in result:
            result = result.split(c)[0]
    return result


def _loop_once():
    """Run the main loop once
    """
    pass


def cycle(iterable):
    """
    Return an iterator that cycles values of a given one
    """
    values = list(iterable)
    while True:
        for value in values:
            yield value


@classmethod
def open(cls, filename):
    """Class method to instantiate from file"""
    return cls(filename)


def Data():
    """
    Data packet, may be Data, Parity, Backup database, may be more.
    """
    return 'Data'


def uniq(s):
    """Filter duplicates while preserving order. ``set`` can almost always be
    used instead of this, but preserving order might prove useful for
    debugging."""
    d = set()
    for x in s:
        if x not in d:
            d.add(x)
            yield x


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 update_current(cursor, tid):
    """
        Update the current object pointers.

        *tid* is the integer tid of the transaction being committed.

        Returns nothing. This does nothing when the storage is history
        free.

        When the storage preserves history, all the objects in
        ``object_state`` having the given *tid* should have their
        (oid, *tid*) stored into ``current_object``. This can be done
        with a single upsert.

        XXX: Why do we need to look at ``object_state``? Is there a
        reason we can't look at the smaller ``temp_store``? Conflict
        resolution maybe?
        """


def kv_string(key, value, *, connector='='):
    """Make Key-Value String."""
    return f'{key}{connector}{value}'


def add_dictval_to_list(adict, key, alist):
    """
    Add a value from a dictionary to a list

    Parameters
    ----------
    adict : dictionary
    key : hashable
    alist : list
        List where value should be added
    """
    if key in adict:
        if isinstance(adict[key], str):
            alist.append(adict[key])
        else:
            alist.extend(adict[key])


def get(name, default=None):
    """
    Get the value of a variable in the settings module scope.
    """
    return globals().get(name, default)


def bytes_to_int(be_bytes):
    """Interprets a big-endian sequence of bytes as an integer"""
    return int.from_bytes(be_bytes, 'big')


@staticmethod
def _adjust_casing(name):
    """We don't want to mix "path" with "PATH", actually we don`t want to mix anything
        with different casing. Furthermore in Windows all is uppercase, but managing all in
        upper case will be breaking."""
    return name.upper() if name.lower() == 'path' else name


@classmethod
def get_fullname(cls):
    """Returns plugins's full name."""
    return '%s@%s' % (cls.get_name(), cls.get_platform() or '')


def rsquared_adj(r, nobs, df_res, has_constant=True):
    """
    Compute the adjusted R^2, coefficient of determination.

    Args:
        r (float): rsquared value
        nobs (int): number of observations the model was fit on
        df_res (int): degrees of freedom of the residuals (nobs - number of model params)
        has_constant (bool): whether the fitted model included a constant (intercept)

    Returns:
        float: adjusted coefficient of determination
    """
    if has_constant:
        return 1.0 - (nobs - 1) / df_res * (1.0 - r)
    else:
        return 1.0 - nobs / df_res * (1.0 - r)


def color_rgbt_to_rgba(rgbt):
    """
    Convert RGBT color to RGBA.

    Convert an RGBT color given as (r, g, b, t) with all values in range [0.255] to the respective color in RGBA. The T is for transparency, an defined as 1 - alpha, where alpha is the RGBA value A.

    Parameters
    ----------
    rgbt: tupel of 4 integers (in range 0..255)
        The color according to RGBT definition, where T is transparency.

    Returns
    -------
    tupel of 4 integers (in range 0..255)
        The color in RGBA notation.

    Examples
    --------
    Convert a color from RGBT to RGBA:

    >>> import brainload.annotations as an
    >>> an.color_rgbt_to_rgba((120, 0, 240, 40))
    (120, 0, 240, 215)
    """
    rgba = rgbt[0], rgbt[1], rgbt[2], 255 - rgbt[3]
    return rgba


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

        :param SharedLinkChangeExpiryDetails val:
        :rtype: EventDetails
        """
    return cls('shared_link_change_expiry_details', val)


def verify_installation(options):
    """ Veryify the installation without trying to install any missing packages
            currently not supported.

            Keyword Arguments:
                options -- argparse opject containing the command line arguments
        """
    print('veryifying the install is currently not supported')


def find_all(first, second=None):
    """Finds all descendants (inorder) of first, including itself.  If second
    is provided, stops when it is reached."""
    regex = first
    while regex and regex is not second:
        yield regex
        regex = regex.next()


def p_param_decl(p):
    """ param_decl : LP param_decl_list RP
    """
    p[0] = p[2]


def _check_arg_length(fname, args, max_fname_arg_count, compat_args):
    """
    Checks whether 'args' has length of at most 'compat_args'. Raises
    a TypeError if that is not the case, similar to in Python when a
    function is called with too many arguments.
    """
    if max_fname_arg_count < 0:
        raise ValueError("'max_fname_arg_count' must be non-negative")
    if len(args) > len(compat_args):
        max_arg_count = len(compat_args) + max_fname_arg_count
        actual_arg_count = len(args) + max_fname_arg_count
        argument = 'argument' if max_arg_count == 1 else 'arguments'
        raise TypeError(
            f'{fname}() takes at most {max_arg_count} {argument} ({actual_arg_count} given)'
            )


def create_replication_job(serverId=None, seedReplicationTime=None,
    frequency=None, licenseType=None, roleName=None, description=None):
    """
    The CreateReplicationJob API is used to create a ReplicationJob to replicate a server on AWS. Call this API to first create a ReplicationJob, which will then schedule periodic ReplicationRuns to replicate your server to AWS. Each ReplicationRun will result in the creation of an AWS AMI.
    See also: AWS API Documentation

    :example: response = client.create_replication_job(
        serverId='string',
        seedReplicationTime=datetime(2015, 1, 1),
        frequency=123,
        licenseType='AWS'|'BYOL',
        roleName='string',
        description='string'
    )

    :type serverId: string
    :param serverId: [REQUIRED] Unique Identifier for a server

    :type seedReplicationTime: datetime
    :param seedReplicationTime: [REQUIRED] Timestamp of an operation

    :type frequency: integer
    :param frequency: [REQUIRED] Interval between Replication Runs. This value is specified in hours, and represents the time between consecutive Replication Runs.

    :type licenseType: string
    :param licenseType: The license type to be used for the Amazon Machine Image (AMI) created after a successful ReplicationRun.

    :type roleName: string
    :param roleName: Name of service role in customer's account to be used by SMS service.

    :type description: string
    :param description: The description for a Replication Job/Run.

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

    :returns:
    (dict) --
    replicationJobId (string) -- The unique identifier for a Replication Job.

    """
    pass


def lineage(resource):
    """
    Return a generator representing the :term:`lineage` of the
    :term:`resource` object implied by the ``resource`` argument.  The
    generator first returns ``resource`` unconditionally.  Then, if
    ``resource`` supplies a ``__parent__`` attribute, return the resource
    represented by ``resource.__parent__``.  If *that* resource has a
    ``__parent__`` attribute, return that resource's parent, and so on,
    until the resource being inspected either has no ``__parent__``
    attribute or which has a ``__parent__`` attribute of ``None``.
    For example, if the resource tree is::

      thing1 = Thing()
      thing2 = Thing()
      thing2.__parent__ = thing1

    Calling ``lineage(thing2)`` will return a generator.  When we turn
    it into a list, we will get::

      list(lineage(thing2))
      [ <Thing object at thing2>, <Thing object at thing1> ]
    """
    while resource is not None:
        yield resource
        try:
            resource = resource.__parent__
        except AttributeError:
            resource = None


@staticmethod
def _check_range(value, minimum, maximum):
    """
        Raise an IndexError if `value` is out of the given range.

        :param value: Value to check
        :param minimum: Minimum value (inclusive)
        :param maximum: Maximum value (inclusive)
        :type value: int
        :type minimum: int
        :type maximum: int

        """
    if value < minimum or value > maximum:
        raise IndexError('Value %r out of range [%r, %r]' % (value, minimum,
            maximum))


def is_recoverable_error(status_code: int) ->bool:
    """
    True if the passed status_code hints at a recoverable server error. I.e. The same request might
    be successful at a later point in time.
    """
    if status_code < 400:
        return False
    if status_code // 100 == 4:
        if status_code in [408, 444, 499]:
            return True
        else:
            return False
    elif status_code // 100 == 5:
        if status_code in [501, 505, 506, 507, 508, 510, 511]:
            return False
        else:
            return True
    else:
        raise ValueError(
            f'Not an Http status code indicating an error: {status_code}')


@classmethod
def properties(cls):
    """
        This allows plugins to utilise blind property data which may be
        utilised by different interfaces for your specific needs.

        This should return a dictionary of the form dict(prop_name=prop_value)
        """
    return dict()


def header(request_headers):
    """将浏览器中的Request Headers头复制过来.进行改装成字典类型

    :param request_headers:  浏览器中的Request Headers头信息
    :return: 分割Headers头信息的键值对
    """
    headers = dict()
    request_headers = request_headers.strip()
    for head in request_headers.rsplit('\n'):
        name, values = head.split(':', 1)
        headers.setdefault(name.strip(), values.strip())
    return headers


@classmethod
def interpret_response(cls, response):
    """
        Populates the response ``service_data`` property with an instance of :class:`RequestTransferExit.ResponseData<udsoncan.services.RequestTransferExit.ResponseData>`

        :param response: The received response to interpret
        :type response: :ref:`Response<Response>`
        """
    response.service_data = cls.ResponseData()
    response.service_data.parameter_records = response.data


def flatten_image_info(sim_dict):
    """
    Sim dict will have structure
        {'g': {'param1': value1}, 'r': {'param1': value2} ...}
    This function will change the structure to
        {'param1_g': value1, 'param1_r': value2, ...}

    :param sim_dict: input sim_dict for ImageGenerator class
    :returns out_dict: flattened sim_dict
    """
    out_dict = {}
    for k, v in sim_dict.items():
        for sim_param, sim_value in v.items():
            out_dict[sim_param + '_' + k] = sim_value
    return out_dict


@classmethod
def extract_keywords(cls, line, items):
    """
        Given the keyword string, parse a dictionary of options.
        """
    unprocessed = list(reversed(line.split('=')))
    while unprocessed:
        chunk = unprocessed.pop()
        key = None
        if chunk.strip() in cls.allowed:
            key = chunk.strip()
        else:
            raise SyntaxError('Invalid keyword: %s' % chunk.strip())
        value = unprocessed.pop().strip()
        if len(unprocessed) != 0:
            for option in cls.allowed:
                if value.endswith(option):
                    value = value[:-len(option)].strip()
                    unprocessed.append(option)
                    break
            else:
                raise SyntaxError('Invalid keyword: %s' % value.split()[-1])
        keyword = '%s=%s' % (key, value)
        try:
            items.update(eval('dict(%s)' % keyword))
        except:
            raise SyntaxError('Could not evaluate keyword: %s' % keyword)
    return items


def add_feature(input_dict):
    """
    Add a feature to Annotated Document Corpus.

    :param adc: Annotated Document Corpus
    :param feature_name: the name of new feature
    :param feature_values: list of features values
    :param feature_value_prefix:  prefix to feature value

    :return: new adc
    """
    for i, document in enumerate(input_dict['adc'].documents):
        document.features[input_dict['feature_name']] = input_dict[
            'feature_value_prefix'] + str(input_dict['feature_values'][i])
    return {'adc': input_dict['adc']}


@classmethod
def get_option_info(cls):
    """Get the default options for this machine."""
    return {'port': (cls.PORT, str)}


def vertex_group_copy():
    """Make a copy of the active vertex group

    """
    pass


def _fill(inst_class, frequencies):
    """This function initializes the frequencies dict with null values. If this
    is not done, it won't be possible to catch missing elements when validating
    the incoming document.
    """
    ctype_info = inst_class.get_flat_type_info(inst_class)
    cfreq_key = inst_class, 0
    for k, v in ctype_info.items():
        if v.Attributes.min_occurs > 0:
            frequencies[cfreq_key][k] = 0


def eval_algorithm(closing, low, high):
    """ Evaluates the SO algorithm

        Args:
            closing: Float of current closing price.
            low: Float of lowest low closing price throughout some duration.
            high: Float of highest high closing price throughout some duration.

        Returns:
            Float SO between 0 and 100.
        """
    if high - low == 0:
        return 100 * (closing - low)
    else:
        return 100 * (closing - low) / (high - low)


def gluTessBeginPolygon(tess, data):
    """Start definition of polygon in the tessellator"""
    return tess.gluTessBeginPolygon(data)