def ran2axis(k, N):
    """needs a doc string"""
    import random as rand
    T = 1.5 + 0.49 * k / N
    B = 0.99 - 0.149 * k / N
    R = (T - B) * rand.random() + B
    return R


def getRules():
    """
        Получить текущие правила firewall'а.

        @return: текстовое представление текущих правил.
        @rtype: C{str}
        """


@staticmethod
def get_version_name():
    """
        Returns version of the DCC
        :return: int
        """
    return ''


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


def backwards_search(p, cl, rank, total_length):
    """Perform backwards search using pattern p, count lookup cl and rank rank

    reference http://alexbowe.com/fm-index/"""
    start = 0
    end = total_length - 1
    for i in range(len(p) - 1, -1, -1):
        if end < start:
            break
        char = p[i]
        count_for_char = cl[char]
        start = count_for_char + rank.rank(start - 1, char)
        end = count_for_char + rank.rank(end, char) - 1
    return start, end


def has_style(node):
    """Tells us if node element has defined styling.

    :Args:
      - node (:class:`ooxml.doc.Element`): Element

    :Returns:
      True or False

    """
    elements = ['b', 'i', 'u', 'strike', 'color', 'jc', 'sz', 'ind',
        'superscript', 'subscript', 'small_caps']
    return any([(True) for elem in elements if elem in node.rpr])


def remove_translation(language):
    """
        remove translation if exists (unregister the translation)
        """


def filter_request_parameters(field_name, msg, look_in_response=False):
    """
    From an event, extract the field name from the message.
    Different API calls put this information in different places, so check a few places.
    """
    val = msg['detail'].get(field_name, None)
    try:
        if not val:
            val = msg['detail'].get('requestParameters', {}).get(field_name,
                None)
        if not val and look_in_response:
            if msg['detail'].get('responseElements'):
                val = msg['detail']['responseElements'].get(field_name, None)
    except AttributeError:
        val = None
    return val


def select_similar_region():
    """Select similar face regions to the current selection

    """
    pass


def p_class_entry_type(p):
    """class_entry_type : CLASS
                        | ABSTRACT CLASS
                        | FINAL CLASS"""
    if len(p) == 3:
        p[0] = p[1].lower()


def fixup_ms(data):
    """
    For whatever reason, the value in IM/ms needs to have a trailing space
    """
    for box in data:
        if 'IM' in data[box]:
            if 'ms' in data[box]['IM']:
                value = data[box]['IM']['ms']
                value[0] = value[0].strip() + ' '
                data[box]['IM']['ms'] = value


def transition_to_state(content, request, to_state, context=None, guards=(),
    skip_same=True):
    """ Execute a transition to another state using a state name
        (``to_state``).  If ``skip_same`` is True, and the
        ``to_state`` is the same as the content state, do nothing."""


def create_network_acl(DryRun=None, VpcId=None):
    """
    Creates a network ACL in a VPC. Network ACLs provide an optional layer of security (in addition to security groups) for the instances in your VPC.
    For more information about network ACLs, see Network ACLs in the Amazon Virtual Private Cloud User Guide .
    See also: AWS API Documentation

    Examples
    This example creates a network ACL for the specified VPC.
    Expected Output:

    :example: response = client.create_network_acl(
        DryRun=True|False,
        VpcId='string'
    )

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

    :type VpcId: string
    :param VpcId: [REQUIRED]
            The ID of the VPC.

    :rtype: dict
    :return: {
        'NetworkAcl': {
            'NetworkAclId': 'string',
            'VpcId': 'string',
            'IsDefault': True|False,
            'Entries': [
                {
                    'RuleNumber': 123,
                    'Protocol': 'string',
                    'RuleAction': 'allow'|'deny',
                    'Egress': True|False,
                    'CidrBlock': 'string',
                    'Ipv6CidrBlock': 'string',
                    'IcmpTypeCode': {
                        'Type': 123,
                        'Code': 123
                    },
                    'PortRange': {
                        'From': 123,
                        'To': 123
                    }
                },
            ],
            'Associations': [
                {
                    'NetworkAclAssociationId': 'string',
                    'NetworkAclId': 'string',
                    'SubnetId': 'string'
                },
            ],
            'Tags': [
                {
                    'Key': 'string',
                    'Value': 'string'
                },
            ]
        }
    }

    """
    pass


def isGColRequired(config, num):
    """A quick helper function that checks whether we need to bother reading the g1,g2 columns.

    It checks the config dict for the output file names gg_file_name, ng_file_name (only if
    num == 1), etc.  If the output files indicate that we don't need the g1/g2 columns, then
    we don't need to raise an error if the g1_col or g2_col is invalid.

    This makes it easier to specify columns. e.g. for an NG correlation function, the
    first catalog does not need to have the g1,g2 columns, and typically wouldn't.  So
    if you specify g1_col=5, g2_col=6, say, and the first catalog does not have these columns,
    you would normally get an error.

    But instead, we check that the calculation is going to be NG from the presence of an
    ng_file_name parameter, and we let the would-be error pass.

    Parameters:
        config (dict):  The configuration file to check.
        num (int):      Which number catalog are we working on.

    Returns:
        True if some output file requires this catalog to have valid g1/g2 columns,
        False if not.

    """
    return config and ('gg_file_name' in config or 'm2_file_name' in config or
        'norm_file_name' in config or num == 1 and 'ng_file_name' in config or
        num == 1 and 'nm_file_name' in config or num == 1 and
        'kg_file_name' in config)


def __contains__(code):
    """True if the language code is known.

        :return: A flag indicating whether the language code is known or not.
        :rtype: bool
        """


def lfu_for_evict(cache_dict, evict_number=1):
    """
    Use LFU(Least Frequently Used) strategy for evicting, the item that number of hits is the least will be removed.

    Test:
    >>> from common_cache import CacheItem
    >>> dict = {}
    >>> dict['a'] = CacheItem(key='a', value=0, expire=5)
    >>> dict['b'] = CacheItem(key='b', value=1, expire=5)
    >>> dict['c'] = CacheItem(key='c', value=2, expire=5)
    >>> len(dict)
    3
    >>> dict['a'].update_hit_count()
    >>> dict['a'].update_hit_count()
    >>> dict['a'].update_hit_count()
    >>> dict['b'].update_hit_count()
    >>> lfu_for_evict(dict)
    ['c']
    >>> lfu_for_evict(dict)
    ['b']
    >>> lfu_for_evict(dict)
    ['a']
    >>> len(dict)
    0
    """
    ordered_dict = sorted(cache_dict.items(), key=lambda t: t[1]['hit_counts'])
    evicted_keys = []
    if len(cache_dict) < evict_number:
        evict_number = len(cache_dict)
    for i in range(evict_number):
        item = ordered_dict[i]
        key = item[0]
        cache_dict.pop(key)
        evicted_keys.append(key)
    return evicted_keys


@staticmethod
def representer(dumper, data):
    """
        YAML representer for MarkdownString.

        We represent MarkdownString as a ``!!str``-tag (I.E.: ``tag:yaml.org,2002:str``),
        with the `literal-scalar style <http://www.yaml.org/spec/1.2/spec.html#id2795688>`_.
        """
    return dumper.represent_scalar(u'tag:yaml.org,2002:str', data.
        unicode_object, style='|')


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


@classmethod
def from_crawler(cls, crawler):
    """Returns instance from crawler.

        Parameters
        ----------
        crawler : scrapy.crawler.Crawler

        Returns
        -------
        RFPDupeFilter
            Instance of RFPDupeFilter.

        """
    return cls.from_settings(crawler.settings)


def _binidx2seglist(binidx):
    """
    ss._binidx2seglist((['f'] * 5) + (['bbb'] * 10) + ['v'] * 5)
    Out: [('f', 0, 5), ('bbb', 5, 15), ('v', 15, 20)]

    #TODO: is there a pandas alternative??
    """
    curlabel = None
    bseg = -1
    ret = []
    for i, e in enumerate(binidx):
        if e != curlabel:
            if curlabel is not None:
                ret.append((curlabel, bseg, i))
            curlabel = e
            bseg = i
    ret.append((curlabel, bseg, i + 1))
    return ret


def format_index_array_attrs(series):
    """Format metadata attributes for and indexed array

    This function is used to provide the necessary metadata to meet
    the (proposed) LIGO Common Data Format specification for series data
    in HDF5.
    """
    attrs = {}
    for i, axis in zip(range(series.ndim), ('x', 'y')):
        unit = '{}unit'.format(axis)
        origin = '{}0'.format(axis)
        delta = 'd{}'.format(axis)
        aunit = getattr(series, unit)
        attrs.update({unit: str(aunit), origin: getattr(series, origin).to(
            aunit).value, delta: getattr(series, delta).to(aunit).value})
    return attrs


def format_time(tm):
    """
    convert time from `{seconds}` to `{hh:mm:ss}`;
    """
    if tm.isdigit():
        tm = int(tm)
        h, m, s = tm // 3600, tm // 60 % 60, tm % 60
        return '{}:'.format(h) * bool(h > 0) + '{:02d}:{:02d}'.format(m, s)
    else:
        return ''


def has_permission(expected, actual):
    """
    Check if singular set of expected/actual
    permissions are appropriate.
    """
    x = set(expected).intersection(actual)
    return len(x) == len(expected)


def get_lowest_payment_for_account(country):
    """ Returns the lowest monthly payment for Klarna Account.
    """
    lpby = {'SE': 50.0, 'NO': 95.0, 'FI': 8.95, 'DK': 89.0, 'DE': 6.95,
        'AT': 6.95, 'NL': 5.0}
    return lpby[country]


def BlendColour(fg, bg, alpha):
    """
    Blends the two colour component `fg` and `bg` into one colour component, adding
    an optional alpha channel.

    :param wx.Colour `fg`: the first colour component;
    :param wx.Colour `bg`: the second colour component;
    :param integer `alpha`: an optional transparency value.
    """
    result = bg + alpha * (fg - bg)
    if result < 0.0:
        result = 0.0
    if result > 255:
        result = 255
    return result


def region_flip():
    """Toggle the region’s alignment (left/right or top/bottom)

    """
    pass


def parent():
    """
        Traverse to the parent of this path.
        """


@classmethod
def init_bare(cls, objects, refs):
    """Create a new bare repository in memory.

        :param objects: Objects for the new repository,
            as iterable
        :param refs: Refs as dictionary, mapping names
            to object SHA1s
        """
    ret = cls()
    for obj in objects:
        ret.object_store.add_object(obj)
    for refname, sha in refs.iteritems():
        ret.refs[refname] = sha
    ret._init_files(bare=True)
    return ret


def store(data, blob):
    """Store the data into the blob
        Raises NonStorable if data is not storable.
        """


def dependents(tokens, head_index):
    """Returns an ordered list of the token indices of the dependents for
    the given head."""
    head_to_deps = {}
    for i, token in enumerate(tokens):
        head = token['dependencyEdge']['headTokenIndex']
        if i != head:
            head_to_deps.setdefault(head, []).append(i)
    return head_to_deps.get(head_index, ())


@classmethod
def encode_data(cls, obj, typedef):
    """Encode an object's data.

        Args:
            obj (object): Object to encode.
            typedef (dict): Type definition that should be used to encode the
                object.

        Returns:
            string: Encoded object.

        """
    raise NotImplementedError('Method must be overridden by the subclass.')


def _defaults_init():
    """
    create & return defaults for all reportlab settings from
    reportlab.rl_settings.py
    reportlab.local_rl_settings.py
    reportlab_settings.py or ~/.reportlab_settings

    latter values override earlier
    """
    from reportlab.lib.utils import rl_exec
    import os
    _DEFAULTS = {}
    rl_exec('from reportlab.rl_settings import *', _DEFAULTS)
    _overrides = _DEFAULTS.copy()
    try:
        rl_exec('from reportlab.local_rl_settings import *', _overrides)
        _DEFAULTS.update(_overrides)
    except ImportError:
        pass
    _overrides = _DEFAULTS.copy()
    try:
        rl_exec('from reportlab_settings import *', _overrides)
        _DEFAULTS.update(_overrides)
    except ImportError:
        _overrides = _DEFAULTS.copy()
        try:
            try:
                fn = os.path.expanduser(os.path.join('~',
                    '.reportlab_settings'))
            except (KeyError, ImportError):
                fn = None
            if fn:
                with open(fn, 'rb') as f:
                    rl_exec(f.read(), _overrides)
                _DEFAULTS.update(_overrides)
        except:
            pass
    return _DEFAULTS


def get_quote(code, data, name):
    """Return special char for quote."""
    if code in data:
        return name, data[code], data[code]
    return name, data['ALL'], data['ALL']


def convertbits(data, frombits, tobits, pad=True):
    """General power-of-2 base conversion."""
    acc = 0
    bits = 0
    ret = []
    maxv = (1 << tobits) - 1
    max_acc = (1 << frombits + tobits - 1) - 1
    for value in data:
        if value < 0 or value >> frombits:
            return None
        acc = (acc << frombits | value) & max_acc
        bits += frombits
        while bits >= tobits:
            bits -= tobits
            ret.append(acc >> bits & maxv)
    if pad:
        if bits:
            ret.append(acc << tobits - bits & maxv)
    elif bits >= frombits or acc << tobits - bits & maxv:
        return None
    return ret


def replace_wildcard(input_list):
    """Method to replace a wildcard `-` in the input values.

    This method will replace the wildcard `-` in the input list; the returned
    two lists have different values on the position of `-`.

    Example: ['0', '-', '1'] => (['0', '0', '1'], ['0', '1', '1'])

    Parameters
    ----------
    input_list : list
        A list of multiple values, possibly with `-` inside.

    Returns
    -------
    list,list
        Two lists differ by the location of `-`.

    """
    if '-' in input_list:
        first_occurrence = input_list.index('-')
        zero_list = input_list[:]
        zero_list[first_occurrence] = '0'
        one_list = input_list[:]
        one_list[first_occurrence] = '1'
        return zero_list, one_list
    else:
        return None, None


def from_x_import_y(x, y):
    """ from mod_name import object_name"""
    module = __import__(x, fromlist=x.rsplit('.', 1)[0])
    return getattr(module, y)


@staticmethod
def merge_or_append_ems_to_pairs(ems_in_slot, pair_id, pairs):
    """if there is an existing ems_pair including the current mention: merge"""
    if pair_id is not None:
        pairs[pair_id].update(ems_in_slot)
    else:
        pairs.append(set(tuple(ems_in_slot)))


@staticmethod
def can_be_applied(graph, candidate, expr_index, sdfg, strict=False):
    """ Returns True if this transformation can be applied on the candidate
            matched subgraph.
            :param graph: SDFGState object if this Transformation is
                          single-state, or SDFG object otherwise.
            :param candidate: A mapping between node IDs returned from
                              `Transformation.expressions` and the nodes in
                              `graph`.
            :param expr_index: The list index from `Transformation.expressions`
                               that was matched.
            :param sdfg: If `graph` is an SDFGState, its parent SDFG. Otherwise
                         should be equal to `graph`.
            :param strict: Whether transformation should run in strict mode.
            :return: True if the transformation can be applied.
        """
    raise NotImplementedError


def provincie_niscode(gemeente_niscode):
    """
    geef de niscode van de provincie op basis van de niscode van de gemeente

    :param gemeente_niscode: niscode van de gemeente
    :return: niscode van de provincie
    """
    pcode = str(gemeente_niscode)[0]
    if pcode == '2':
        return int('20001')
    else:
        return int('{0}0000'.format(pcode))


def test():
    """
    Run git-sweep's test suite.
    """
    import nose
    import sys
    nose.main(argv=['nose'] + sys.argv[1:])


def inverse(pattern):
    """ gets the inverse pattern of a pattern """
    new_pattern = ''
    for item in pattern:
        if item == '0':
            new_pattern += '1'
        elif item == '1':
            new_pattern += '0'
        else:
            new_pattern += item
    return new_pattern


def _dumx_remove(dumx, dumx_flat, p0):
    """
    remove p0 from dumx
    """
    res = []
    for dx in dumx:
        if p0 not in dx:
            res.append(dx)
            continue
        k = dx.index(p0)
        if k % 2 == 0:
            p0_paired = dx[k + 1]
        else:
            p0_paired = dx[k - 1]
        dx.remove(p0)
        dx.remove(p0_paired)
        dumx_flat.remove(p0)
        dumx_flat.remove(p0_paired)
        res.append(dx)


def remove():
    """Mark chunk data as removed (does nothing by default)"""


def reverse_dict(d):
    """Reverse a dictionary so the items become the keys and vice-versa.

    Note: The results will be arbitrary if the items are not unique.

    >>> d = reverse_dict({'a': 1, 'b': 2})
    >>> d_items = d.items()
    >>> d_items.sort()
    >>> d_items
    [(1, 'a'), (2, 'b')]

    """
    result = {}
    for key, value in d.items():
        result[value] = key
    return result


def get_transaction_details(transactionid):
    """ GetTransactionDetails """


def SizeReserveUernPremEnd(t):
    """Unearned reserve per policy: End of period"""
    return 0


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


def find_plot_bounds(f, guess, N=101, zmax=1000):
    """Find reasonable area to plot for stability regions.

    Tries to find an area that contains the entire region where f returns True,
    but isn't too big.  Makes lots of assumptions and is really intended for
    finding stability regions.  Obviously can't work for unbounded stability
    regions.

    f should return True if f(z) is in the stability region.

    N should be odd in order to catch very small stability regions.
    """
    import numpy as np
    bounds = guess
    old_bounds = []
    while bounds != old_bounds:
        old_bounds = bounds
        y = np.linspace(bounds[2], bounds[3], N)
        bounds = list(bounds)
        close = False
        while abs(bounds[0]) < zmax:
            x = np.linspace(bounds[0], bounds[1], N)
            Z = x[0] + y * 1.0j
            left = f(Z)
            if np.any(left):
                bounds[0] = 1.5 * bounds[0]
                close = True
            else:
                if close == True:
                    break
                bounds[0] = bounds[0] / 1.5
                if bounds[0] > -1e-15:
                    return bounds
        bounds[1] = -0.1 * bounds[0]
        x = np.linspace(bounds[0], bounds[1], N) + 0.0 * 1.0j
        close = False
        while abs(bounds[2]) < zmax:
            y = np.linspace(bounds[2], bounds[3], N)
            Z = x + y[0] * 1.0j
            bottom = f(Z)
            if np.any(bottom):
                bounds[2] = 1.5 * bounds[2]
                close = True
            else:
                if close == True:
                    break
                bounds[2] = bounds[2] / 1.5
                if bounds[2] > -1e-15:
                    return bounds
        bounds[3] = -bounds[2]
    return bounds


def _instance2sub(instance_number, total_perturbations):
    """
    Converts an instance number (ii) to initial condition index (ci) and
    perturbation index (pi)  subscripts

    instances use 1-based indexes and vary according to this function:
        ii = ci * len(PERTURBATIONS) + pi + 1
    where both pi and ci use 0-based indexes.
    """
    perturbation_index = (instance_number - 1) % total_perturbations
    initial_condition = (instance_number - 1 - perturbation_index
        ) // total_perturbations
    return initial_condition, perturbation_index


def psi_Mg_Na_Cl_HMW84(T, P):
    """c-c'-a: magnesium sodium chloride [HMW84]."""
    psi = -0.012
    valid = T == 298.15
    return psi, valid


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


def __get_station(seedid):
    """Station name from seed id"""
    st = seedid.rsplit('.', 2)[0]
    if st.startswith('.'):
        st = st[1:]
    return st


@staticmethod
def pkg_in_cache(pkgid, cache):
    """
        pkg_apt needs to override this for multiarch support.
        """
    return pkgid in cache


def _add_force_arg(arg_parser, help_text):
    """
    Adds optional force parameter to a parser.
    :param arg_parser: ArgumentParser parser to add this argument to.
    :param help_text: str label displayed in usage
    """
    arg_parser.add_argument('--force', help=help_text, action='store_true',
        dest='force')


def best_observer(population, num_generations, num_evaluations, args):
    """Print the best individual in the population to the screen.

    This function displays the best individual in the population to
    the screen.

    .. Arguments:
       population -- the population of Individuals
       num_generations -- the number of elapsed generations
       num_evaluations -- the number of candidate solution evaluations
       args -- a dictionary of keyword arguments

    """
    print('Best Individual: {0}\n'.format(str(max(population))))


def remove_tags_from_resource(ResourceId=None, TagKeys=None):
    """
    Removes tags from a directory.
    See also: AWS API Documentation

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

    :type ResourceId: string
    :param ResourceId: [REQUIRED]
            Identifier (ID) of the directory from which to remove the tag.

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

    :rtype: dict
    :return: {}

    :returns:
    (dict) --

    """
    pass


@classmethod
def get_initkwargs(cls, form_list=None, initial_dict=None, instance_dict=
    None, condition_dict=None, *args, **kwargs):
    """Create a dict with all needed parameters.

         For the form wizard instances.

        * `form_list` - is a list of forms. The list entries can be single form
          classes or tuples of (`step_name`, `form_class`). If you pass a list
          of forms, the wizardview will convert the class list to
          (`zero_based_counter`, `form_class`). This is needed to access the
          form for a specific step.
        * `initial_dict` - contains a dictionary of initial data dictionaries.
          The key should be equal to the `step_name` in the `form_list` (or
          the str of the zero based counter - if no step_names added in the
          `form_list`)
        * `instance_dict` - contains a dictionary whose values are model
          instances if the step is based on a ``ModelForm`` and querysets if
          the step is based on a ``ModelFormSet``. The key should be equal to
          the `step_name` in the `form_list`. Same rules as for `initial_dict`
          apply.
        * `condition_dict` - contains a dictionary of boolean values or
          callables. If the value of for a specific `step_name` is callable it
          will be called with the wizardview instance as the only argument.
          If the return value is true, the step's form will be used.
        """
    kwargs.update({'initial_dict': initial_dict or kwargs.pop(
        'initial_dict', getattr(cls, 'initial_dict', None)) or {},
        'instance_dict': instance_dict or kwargs.pop('instance_dict',
        getattr(cls, 'instance_dict', None)) or {}, 'condition_dict':
        condition_dict or kwargs.pop('condition_dict', getattr(cls,
        'condition_dict', None)) or {}})
    return kwargs


def get_blk_string(block):
    """
    Format the given block id to string

    :param block: memory block id or block string.
    :type string: like 198 or memory198
    :return: returns string memory198 if id 198 is given
    :rtype: string
    """
    if not block.startswith('memory'):
        return 'memory%s' % block
    return block


def _import_dcm():
    """DICOM Import function (checking for required libraries):
    DICOM support requires library `pydicom`"""
    import logging
    logger = logging.getLogger('pydicom')
    logger.setLevel(logging.CRITICAL)
    try:
        from pydicom import dicomio
    except ImportError:
        import dicom as dicomio
    logger.setLevel(logging.WARNING)


@classmethod
def get_cls_config(cls):
    """ Returns class configuration. """
    return cls.get_config(cls)


@classmethod
def associate_with_attribute(cls, attribute):
    """Establish this type as a mutation listener for the given
        mapped descriptor.

        """
    cls._listen_on_attribute(attribute, True, attribute.class_)


@classmethod
def fromData(cls, type, data, startOffset=0):
    """
        Create an instance of the SequenceEvent subclass this function
        is called on, using a particular type value and reading data
        beginning at some offset. This abstract base class
        implementation simply raises NotImplementedError.
        """
    raise NotImplementedError(
        'SequenceEvent subclasses that can load themselves from data without context can implement this.'
        )


def create_vol_geom(*varargin):
    """Create a volume geometry structure.

This method can be called in a number of ways:

``create_vol_geom(N)``:
    :returns: A 2D volume geometry of size :math:`N \\times N`.

``create_vol_geom((Y, X))``:
    :returns: A 2D volume geometry of size :math:`Y \\times X`.

``create_vol_geom(Y, X)``:
    :returns: A 2D volume geometry of size :math:`Y \\times X`.

``create_vol_geom(Y, X, minx, maxx, miny, maxy)``:
    :returns: A 2D volume geometry of size :math:`Y \\times X`, windowed as :math:`minx \\leq x \\leq maxx` and :math:`miny \\leq y \\leq maxy`.

``create_vol_geom((Y, X, Z))``:
    :returns: A 3D volume geometry of size :math:`Y \\times X \\times Z`.

``create_vol_geom(Y, X, Z)``:
    :returns: A 3D volume geometry of size :math:`Y \\times X \\times Z`.

``create_vol_geom(Y, X, Z, minx, maxx, miny, maxy, minz, maxz)``:
    :returns: A 3D volume geometry of size :math:`Y \\times X \\times Z`, windowed as :math:`minx \\leq x \\leq maxx` and :math:`miny \\leq y \\leq maxy` and :math:`minz \\leq z \\leq maxz` .

"""
    vol_geom = {'option': {}}
    if len(varargin) == 1 and isinstance(varargin[0], int) == 1:
        vol_geom['GridRowCount'] = varargin[0]
        vol_geom['GridColCount'] = varargin[0]
        vol_geom['option']['WindowMinX'] = -varargin[0] / 2.0
        vol_geom['option']['WindowMaxX'] = varargin[0] / 2.0
        vol_geom['option']['WindowMinY'] = -varargin[0] / 2.0
        vol_geom['option']['WindowMaxY'] = varargin[0] / 2.0
    elif len(varargin) == 1 and len(varargin[0]) == 2:
        vol_geom['GridRowCount'] = varargin[0][0]
        vol_geom['GridColCount'] = varargin[0][1]
        vol_geom['option']['WindowMinX'] = -varargin[0][1] / 2.0
        vol_geom['option']['WindowMaxX'] = varargin[0][1] / 2.0
        vol_geom['option']['WindowMinY'] = -varargin[0][0] / 2.0
        vol_geom['option']['WindowMaxY'] = varargin[0][0] / 2.0
    elif len(varargin) == 1 and len(varargin[0]) == 3:
        vol_geom['GridRowCount'] = varargin[0][0]
        vol_geom['GridColCount'] = varargin[0][1]
        vol_geom['GridSliceCount'] = varargin[0][2]
        vol_geom['option']['WindowMinX'] = -varargin[0][1] / 2.0
        vol_geom['option']['WindowMaxX'] = varargin[0][1] / 2.0
        vol_geom['option']['WindowMinY'] = -varargin[0][0] / 2.0
        vol_geom['option']['WindowMaxY'] = varargin[0][0] / 2.0
        vol_geom['option']['WindowMinZ'] = -varargin[0][2] / 2.0
        vol_geom['option']['WindowMaxZ'] = varargin[0][2] / 2.0
    elif len(varargin) == 2:
        vol_geom['GridRowCount'] = varargin[0]
        vol_geom['GridColCount'] = varargin[1]
        vol_geom['option']['WindowMinX'] = -varargin[1] / 2.0
        vol_geom['option']['WindowMaxX'] = varargin[1] / 2.0
        vol_geom['option']['WindowMinY'] = -varargin[0] / 2.0
        vol_geom['option']['WindowMaxY'] = varargin[0] / 2.0
    elif len(varargin) == 6:
        vol_geom['GridRowCount'] = varargin[0]
        vol_geom['GridColCount'] = varargin[1]
        vol_geom['option']['WindowMinX'] = varargin[2]
        vol_geom['option']['WindowMaxX'] = varargin[3]
        vol_geom['option']['WindowMinY'] = varargin[4]
        vol_geom['option']['WindowMaxY'] = varargin[5]
    elif len(varargin) == 3:
        vol_geom['GridRowCount'] = varargin[0]
        vol_geom['GridColCount'] = varargin[1]
        vol_geom['GridSliceCount'] = varargin[2]
    elif len(varargin) == 9:
        vol_geom['GridRowCount'] = varargin[0]
        vol_geom['GridColCount'] = varargin[1]
        vol_geom['GridSliceCount'] = varargin[2]
        vol_geom['option']['WindowMinX'] = varargin[3]
        vol_geom['option']['WindowMaxX'] = varargin[4]
        vol_geom['option']['WindowMinY'] = varargin[5]
        vol_geom['option']['WindowMaxY'] = varargin[6]
        vol_geom['option']['WindowMinZ'] = varargin[7]
        vol_geom['option']['WindowMaxZ'] = varargin[8]
    return vol_geom


def Convert2Days(time, units, calendar):
    """
		Convert an array of times with given units and calendar
		 into the same times but in units of days.
	"""
    import netCDF4 as nc
    import netcdftime as nct
    date = nc.num2date(time, units, calendar)
    unitArray = units.split()
    dayUnits = units.replace(unitArray[0], 'days')
    t = nct.utime(dayUnits, calendar=calendar)
    return t.date2num(date)


def check_chamber(chamber):
    """Validate that chamber is house or senate"""
    if str(chamber).lower() not in ('house', 'senate'):
        raise TypeError('chamber must be either "house" or "senate"')


def get_total_scan_point(hdr):
    """
    Find the how many data points are recorded. This number may not equal to the total number
    defined at the start of the scan due to scan stop or abort.
    """
    evs = hdr.events()
    n = 0
    try:
        for e in evs:
            n = n + 1
    except IndexError:
        pass
    return n


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

        :param EmmAddExceptionType val:
        :rtype: EventType
        """
    return cls('emm_add_exception', val)


@classmethod
def clear_url_adapter_cache(cls, *args):
    """
        A method which conveniently clears the cache
        """
    cls._url_adapter_cache.clear()


@classmethod
def chunk_bytes(cls, data):
    """
        Chunks some data up so it can be sent in reasonable size messages.
        Yields (chunk, last_chunk) tuples.
        """
    position = 0
    if not data:
        yield data, True
        return
    while position < len(data):
        yield data[position:position + cls.chunk_size
            ], position + cls.chunk_size >= len(data)
        position += cls.chunk_size


def feature_parser(uni_feature, word_surface):
    """
    Parse the POS feature output by Mecab
    :param uni_feature unicode:
    :return ( (pos1, pos2, pos3), word_stem ):
    """
    list_feature_items = uni_feature.split(',')
    if len(list_feature_items) == 1:
        return '*', '*'
    pos1 = list_feature_items[0]
    pos2 = list_feature_items[1]
    pos3 = list_feature_items[2]
    tuple_pos = pos1, pos2, pos3
    if len(list_feature_items) == 9:
        word_stem = list_feature_items[6]
    else:
        word_stem = word_surface
    return tuple_pos, word_stem


def _dumpNdarrayToFile(filelike, ndarray):
    """Serializes an N-dimensional ``numpy.array`` to bytes, writes the bytes to
    the filelike object and returns a dictionary with metadata, necessary to
    restore the ``numpy.array`` from the file.

    :param filelike: can be a file or a file-like object that provides the
        methods ``.write()`` and ``.tell()``.
    :param ndarray: a N-dimensional ``numpy.array``

    :returns: a metadata dictionary ::
        {'start': start position in the file, 'end': end position in the file,
         'size': size of the array, 'dtype': numpy data type of the array,
         'shape': description of the array shape
         }
    """
    bytedata = ndarray.tobytes('C')
    start = filelike.tell()
    end = start + len(bytedata)
    metadata = {'start': start, 'end': end, 'size': ndarray.size, 'dtype':
        ndarray.dtype.name, 'shape': ndarray.shape}
    filelike.write(bytedata)
    return metadata


def cal_error(array, typeb=0):
    """Calculate all errors of the input array.

    Args:
        array (numpy.array): The data measured directly for a single
            physical datus. We use the mean value as the reliable
            measurement for that and get type-A error meanwhile.
        typeb (float): The type-B error collected directly from the
            instrucments.

    Returns:
        mean (float): The mean value of the array.
        delta_a (float): The type-A error of the array.
        error (float): The merged error of type-A and type-B

    """
    size = array.size
    mean = array.mean()
    std = array.std(ddof=1)
    params = {(3): 2.48, (4): 1.59, (5): 1.204, (6): 1.05, (7): 0.926, (8):
        0.834, (9): 0.77, (10): 0.715}
    delta_a = std * params[size]
    if typeb == 0:
        return mean, delta_a
    deltb_b = typeb
    error = (delta_a ** 2 + deltb_b ** 2) ** 0.5
    return mean, delta_a, deltb_b


def add_output_compression_type(parser):
    """Add compression arguments to a parser object."""
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--gzip', default=False, action='store_true', help=
        'Compress output using gzip')
    group.add_argument('--bzip', default=False, action='store_true', help=
        'Compress output using bzip2')


def subpaths(path):
    """
    Yields a `(last part, subpath)` tuple for all possible sub-paths of `path`.

    >>> list(subpaths("foo/bar/spam"))
    [('foo', 'foo'), ('bar', 'foo/bar'), ('spam', 'foo/bar/spam')]
    """
    seen = []
    for part in path.split('/'):
        seen.append(part)
        yield part, '/'.join(seen)


def _get_request(context):
    """
    Fetch the request from the context.
    This enforces the use of the template :class:`~django.template.RequestContext`,
    and provides meaningful errors if this is omitted.
    """
    assert 'request' in context, "The fluent_pages_tags library requires a 'request' object in the context! Is RequestContext not used, or 'django.core.context_processors.request' not included in TEMPLATE_CONTEXT_PROCESSORS?"
    return context['request']


def __rsub__(other):
    """set - extent: given BTrees.IFBTree data structure, return difference"""


def board_termsize(board_width, board_height):
    """
    Function board_termsize returns the height and width of a grid of
    characters needed to display a board with the given input dimensions.
    """
    cwidth = 3
    termwidth = (cwidth + 1) * board_width + 1
    termheight = board_height * 2 + 1
    return termwidth, termheight


@staticmethod
def get_addresses_model():
    """
        This is needed so the BaseState can validate the
        provided addresses and throw an error if any are missing.
        As well as automatically generate documentation.
        NOTE: types must always be "str"
        return = {
            'required_addresses': {
                'req_address_name_1': str,
                'req_address_name_2': str,
            },
            'optional_addresses': {
                'opt_address_name_1': str,
                'opt_address_name_2': str,
            },
        }
        """
    return {'required_addresses': {'publisher': str}, 'optional_addresses': {}}


def getMedian(numericValues):
    """
    Gets the median of a list of values
    Returns a float/int
    """
    theValues = sorted(numericValues)
    if len(theValues) % 2 == 1:
        return theValues[(len(theValues) + 1) / 2 - 1]
    else:
        lower = theValues[len(theValues) / 2 - 1]
        upper = theValues[len(theValues) / 2]
        return float(lower + upper) / 2


def _best_color_match(orig_color, colors):
    """
    Match provided color for closed match in colors list, and return it's
    index and delta (which indicates similarity)
    """
    delta = 0
    src_r, src_g, src_b = orig_color
    rgb_diff = 195075
    for idx, (pal_r, pal_g, pal_b) in enumerate(colors):
        partial_delta = (src_r - pal_r) ** 2 + (src_g - pal_g) ** 2 + (src_b -
            pal_b) ** 2
        if partial_delta == 0:
            delta = partial_delta
            color2use = idx
            break
        if rgb_diff > partial_delta:
            rgb_diff = partial_delta
            delta = rgb_diff
            color2use = idx
    return color2use, delta


def alpha_for_abruptly_changing_env(nu=0.5):
    """For abruptly-changing environement, if the number of break-points is :math:`\\Upsilon_T = \\mathcal{O}(T^{\\nu})`, then the SW-UCB# algorithm chooses :math:`\\alpha = \\frac{1-\\nu}{2}`."""
    return (1 - nu) / 2


def _add_doc(func, doc):
    """Add documentation to a function."""
    func.__doc__ = doc


@classmethod
def validate(klass, input_value):
    """
        Validate input values to store into Froshki._data.

        klass.validate(input_value)
            -> True, input_value
        or
            -> False, error_message
        Override this method for customization.
        """
    return True, input_value


@classmethod
def get_template_groups(cls):
    """Note that `get_template_groups` is a **class method** on
        `PrintableType` but an **instance method** on `Printable`.

        """
    return [str(cls.templates_group)]


def dtype_to_matlab_class(dtype):
    """
    convert dtype to matlab class string
    """
    if dtype.str in ['<f8']:
        return 'double'
    elif dtype.str in ['<f4']:
        return 'single'
    elif dtype.str in ['<i8']:
        return 'int64'
    elif dtype.str in ['<u8']:
        return 'uint64'
    elif dtype.str in ['<i4']:
        return 'int32'
    elif dtype.str in ['<u4']:
        return 'uint32'
    elif dtype.str in ['<i2']:
        return 'int16'
    elif dtype.str in ['<u2']:
        return 'uint16'
    elif dtype.str in ['|i1']:
        return 'int8'
    elif dtype.str in ['|u1']:
        return 'uint8'


@staticmethod
def to_json(df, x, y):
    """Format output for json response."""
    values = []
    for i, row in df.iterrows():
        values.append({'x': row[x], 'y': row[y]})
    return {'result': values}


def include_node(tag, node, group):
    """Given an aiida-node and a (string) tag, add the node in the curated-cof_XXX_vX group,
    and set the tag as the extra of the node for the query.
    """
    node.set_extra('curated-cof_tag', tag)
    group.add_nodes(node)


def cropSilenceInEdges(sampleList, silenceThreshold, sampleFreq):
    """
    Returns the left and right boundaries of the meaningful data in a wav file
    """
    startI = 0
    while sampleList[startI] < silenceThreshold:
        startI += 1
    endI = len(sampleList) - 1
    while sampleList[endI] < silenceThreshold:
        endI -= 1
    startTime = startI * sampleFreq
    endTime = endI * sampleFreq
    return startTime, endTime


def human_readable(value):
    """make the given string nice and human readable
    """
    label = value.replace('.', ' ').replace('_', ' ')
    label = label.title()
    label = label.strip()
    return label


def make_social_name(txt):
    """from a link like http://foo.com/username returns username"""
    return txt.split('/')[-1]


def lock():
    """Lock strips so they can’t be transformed

    """
    pass


@staticmethod
def p_daq_event_optional_list(p):
    """daq_event_optional_list : daq_event_optional
                                   | daq_event_optional daq_event_optional_list"""
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


def paginate(cur_page, total_pages):
    """ Compute the range of pages that should be displayed to the user. """
    if total_pages <= 9:
        return 1, total_pages
    if cur_page < 5:
        return 1, 9
    if cur_page > total_pages - 4:
        return total_pages - 8, total_pages
    return cur_page - 4, cur_page + 4


def intersection(l1, l2):
    """Returns intersection of two lists.  Assumes the lists are sorted by start positions"""
    if len(l1) == 0 or len(l2) == 0:
        return []
    out = []
    l2_pos = 0
    for l in l1:
        while l2_pos < len(l2) and l2[l2_pos].end < l.start:
            l2_pos += 1
        if l2_pos == len(l2):
            break
        while l2_pos < len(l2) and l.intersects(l2[l2_pos]):
            out.append(l.intersection(l2[l2_pos]))
            l2_pos += 1
        l2_pos = max(0, l2_pos - 1)
    return out


def _ex_type_str(exobj):
    """ Returns a string corresponding to the exception type """
    return str(exobj).split("'")[1].split('.')[-1]


def get_task_prerun_attachment(task_id, task, args, kwargs, **cbkwargs):
    """Create the slack message attachment for a task prerun."""
    message = 'Executing -- ' + task.name.rsplit('.', 1)[-1]
    lines = ['Name: *' + task.name + '*']
    if cbkwargs['show_task_id']:
        lines.append('Task ID: ' + task_id)
    if cbkwargs['use_fixed_width']:
        if cbkwargs['show_task_args']:
            lines.append('args: ' + '`' + str(args) + '`')
        if cbkwargs['show_task_kwargs']:
            lines.append('kwargs: ' + '`' + str(kwargs) + '`')
    else:
        if cbkwargs['show_task_args']:
            lines.append('args: ' + str(args))
        if cbkwargs['show_task_kwargs']:
            lines.append('kwargs: ' + str(kwargs))
    executing = '\n'.join(lines)
    attachment = {'attachments': [{'fallback': message, 'color': cbkwargs[
        'slack_task_prerun_color'], 'text': executing, 'title': message,
        'mrkdwn_in': ['text']}], 'text': ''}
    if cbkwargs['flower_base_url']:
        attachment['attachments'][0]['title_link'] = cbkwargs['flower_base_url'
            ] + '/task/{tid}'.format(tid=task_id)
    return attachment


def gilbert_damping(x, alpha, df0):
    """
    A Linear model f=x -> alpha* x + df0. Returns the frequency domain half
    width half maximum (HWHM).
    """
    f = x
    return alpha * f + df0


@staticmethod
def rmul(*args):
    """
        Return product of Permutations [a, b, c, ...] as the Permutation whose
        ith value is a(b(c(i))).

        a, b, c, ... can be Permutation objects or tuples.

        Examples
        ========

        >>> from sympy.combinatorics.permutations import _af_rmul, Permutation
        >>> Permutation.print_cyclic = False

        >>> a, b = [1, 0, 2], [0, 2, 1]
        >>> a = Permutation(a); b = Permutation(b)
        >>> list(Permutation.rmul(a, b))
        [1, 2, 0]
        >>> [a(b(i)) for i in range(3)]
        [1, 2, 0]

        This handles the operands in reverse order compared to the ``*`` operator:

        >>> a = Permutation(a); b = Permutation(b)
        >>> list(a*b)
        [2, 0, 1]
        >>> [b(a(i)) for i in range(3)]
        [2, 0, 1]

        Notes
        =====

        All items in the sequence will be parsed by Permutation as
        necessary as long as the first item is a Permutation:

        >>> Permutation.rmul(a, [0, 2, 1]) == Permutation.rmul(a, b)
        True

        The reverse order of arguments will raise a TypeError.

        """
    rv = args[0]
    for i in range(1, len(args)):
        rv = args[i] * rv
    return rv


def is_newline_error(e):
    """
    Return True is e is a new line error based on the error text.
    Otherwise return False.
    """
    newline_error = (
        u'new-line character seen in unquoted field - do you need to open the file in universal-newline mode?'
        )
    return newline_error == str(e)


def setdefault(object, attribute, producer):
    """
    Like dict().setdefault but for object attributes.
    """
    if not hasattr(object, attribute):
        setattr(object, attribute, producer())
    return getattr(object, attribute)


@staticmethod
def format_num(n):
    """
        Intelligent scientific notation (.3g).

        Parameters
        ----------
        n  : int or float or Numeric
            A Number.

        Returns
        -------
        out  : str
            Formatted number.
        """
    f = '{0:.3g}'.format(n).replace('+0', '+').replace('-0', '-')
    n = str(n)
    return f if len(f) < len(n) else n


def handle_commits_log_argument(terminal_pairs_as_tuples) ->bool:
    """
    Handle log argument.
    """
    logs = False
    for i, pair in enumerate(terminal_pairs_as_tuples):
        flag, value = pair[0], pair[1]
        if flag == 'log':
            if value:
                logs = True
            del terminal_pairs_as_tuples[i]
    return logs


def _generateSpecial_Volume3DOpts_clipPlane(overlayList, displayCtx, source,
    longArg):
    """Generates arguemnts for the ``Volume3DOpts.clipPlane`` option. """
    args = []
    for i in range(source.numClipPlanes):
        args += [longArg, '{:0.3f}'.format(source.clipPosition[i]),
            '{:0.3f}'.format(source.clipAzimuth[i]), '{:0.3f}'.format(
            source.clipInclination[i])]
    return args


def is_in_revision(context):
    """Returns whether the passed context is considered in revision.
        """


@staticmethod
def after_start(job):
    """
		Set the status & report to slack
		:param job:
		:return:
		"""
    pass


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

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

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


@classmethod
def congruent(cls, mat_1, mat_2):
    """Compute the congruent action of mat_2 on mat_1.

        This is :math: `mat_2 mat_1 mat_2^T`.

        Parameters
        ----------
        mat_1 : array-like, shape=[n_samples, n, n]
        mat_2 : array-like, shape=[n_samples, n, n]

        Returns
        -------
        cong : array-like, shape=[n_samples, n, n]
        """
    return cls.mul(mat_2, mat_1, cls.transpose(mat_2))


def import_class(class_path):
    """
    Returns class from the given path.

    For example, in order to get class located at
    ``mypackage.subpackage.MyClass``:

        try:
            hgrepo = import_class('mypackage.subpackage.MyClass')
        except ImportError:
            # hadle error
    """
    splitted = class_path.split('.')
    mod_path = '.'.join(splitted[:-1])
    class_name = splitted[-1]
    class_mod = __import__(mod_path, {}, {}, [class_name])
    try:
        cls = getattr(class_mod, class_name)
    except AttributeError:
        raise ImportError("Couldn't import %r" % class_path)
    return cls


@classmethod
def named_volume_for_db_data(cls, db_env: 'DbEnvironments', env_name: str):
    """Returns the name of the named volume for this database environment"""
    return f'{cls.named_volume_prefix_for(db_env)}{env_name}'


def _wider_test_jpeg(data):
    """Test for a jpeg file following the UNIX file implementation which
    uses the magic bytes rather than just looking for the bytes that
    represent 'JFIF' or 'EXIF' at a fixed position.
    """
    if data[:2] == b'\xff\xd8':
        return 'jpeg'


def net(f, c='close', o=1):
    """Calculate the net change of a given column.

    Parameters
    ----------
    f : pandas.DataFrame
        Dataframe containing the column ``c``.
    c : str
        Name of the column in the dataframe ``f``.
    o : int, optional
        Offset value for shifting the series.

    Returns
    -------
    new_column : pandas.Series (float)
        The array containing the new feature.

    References
    ----------
    *Net change is the difference between the closing price of a security
    on the day's trading and the previous day's closing price. Net change
    can be positive or negative and is quoted in terms of dollars* [IP_NET]_.

    .. [IP_NET] http://www.investopedia.com/terms/n/netchange.asp

    """
    new_column = f[c] - f[c].shift(o)
    return new_column


@classmethod
def get_class_url_lazy(cls, url_name, attr_name, *args, **kwargs):
    """
        `attr_name` should be a valid Python identifier; preferrably, make it
        similar to `url_name` and start with an underscore.
        """
    if not hasattr(cls, attr_name):
        url = cls.get_class_url(url_name, *args, **kwargs)
        setattr(cls, attr_name, url)
    return getattr(cls, attr_name)


def generate_primes():
    """
    Generate an infinite sequence of prime numbers.

    The algorithm was originally written by David Eppstein, UC Irvine. See:
    http://code.activestate.com/recipes/117119/

    Examples
    --------
    >>> g = generate_primes()
    >>> next(g)
    2
    >>> next(g)
    3
    >>> next(g)
    5
    """
    divisors = {}
    candidate = 2
    while True:
        if candidate in divisors:
            for p in divisors[candidate]:
                divisors.setdefault(p + candidate, []).append(p)
            del divisors[candidate]
        else:
            yield candidate
            divisors[candidate * candidate] = [candidate]
        candidate += 1


def detect_inside_virtualenv(prefix, real_prefix, base_prefix):
    """Tell if fades is running inside a virtualenv.

    The params 'real_prefix' and 'base_prefix' may be None.

    This is copied from pip code (slightly modified), see

        https://github.com/pypa/pip/blob/281eb61b09d87765d7c2b92f6982b3fe76ccb0af/
            pip/locations.py#L39
    """
    if real_prefix is not None:
        return True
    if base_prefix is None:
        return False
    return prefix != base_prefix


def chunk(seq, num):
    """
    cut list into n chunks
    """
    avg = len(seq) / float(num)
    out = []
    last = 0.0
    while last < len(seq):
        out.append(seq[int(last):int(last + avg)])
        last += avg
    return out


@classmethod
def delete_subscript(class_, script, subscript):
    """
        Returns a script with the given subscript removed. The subscript
        must appear in the main script aligned to opcode boundaries for it
        to be removed.
        """
    new_script = bytearray()
    pc = 0
    for opcode, data, pc, new_pc in class_.ScriptTools.get_opcodes(script):
        section = script[pc:new_pc]
        if section != subscript:
            new_script.extend(section)
    return bytes(new_script)


def __ne__(A, other):
    """Returns true if both objects are not equal"""
    return not A == other


def get_py4DSTEM_topgroup(h5_file):
    """
    Accepts an open h5py File boject. Returns string of the top group name.
    """
    if '4DSTEM_experiment' in h5_file.keys():
        return '4DSTEM_experiment/'
    elif '4DSTEM_simulation' in h5_file.keys():
        return '4DSTEM_simulation/'
    else:
        return '4D-STEM_data/'


def load(filename):
    """Load a :class:`ClusterTree` or :class:`BlockClusterTree` from file

    :param filename: file to import
    :type filename: String
    :return: object
    :rtype: BlockClusterTree or ClusterTree

    .. note:: Depends on :mod:`pickle`
    """
    import pickle
    with open(filename, 'rb') as infile:
        obj = pickle.load(infile)
    return obj


def add_point_slide(PAINTCURVE_OT_add_point=None, PAINTCURVE_OT_slide=None):
    """Add new curve point and slide it

    :param PAINTCURVE_OT_add_point: Add New Paint Curve Point, Add New Paint Curve Point
    :param PAINTCURVE_OT_slide: Slide Paint Curve Point, Select and slide paint curve point
    """
    pass


def format_pvalue(pval):
    """Latex compatible representations

    """
    pval = str('%.1g' % pval)
    if 'e' in pval:
        pval += '}'
        pval = pval.replace('e', '*10^{').replace('-0', '-')
    return pval


def clean_doc(*values):
    """Clean doc string."""
    for v in values:
        v = v and v.split('---')[0].strip()
        if v:
            return v
    return None


@classmethod
def update_attributes_map(klass):
    """
        Attributes for object mapping.
        """
    return {'name': '', 'description': '', 'display_field': '', 'fields': []}


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

    :param name: Name, Name of the preset, used to make the path name
    :type name: str
    :param remove_name: remove_name
    :type remove_name: bool
    :param remove_active: remove_active
    :type remove_active: bool
    """
    pass


def __mock_sources(sources):
    """
    Create mock sources

    :param sources:  List of sources
    :return:         List of mock sources
    """
    tmp_sources = []
    for source in sources:
        tmp_sources.append((source[0], ':'.join(['mock'] + source[1].split(
            ':')[1:]), source[2], source[3]))
    sources = tmp_sources
    return tmp_sources


def get_all(isamAppliance, check_mode=False, force=False):
    """
    Retrieving a list of all LDAP server connections
    """
    return isamAppliance.invoke_get(
        'Retrieving a list of all LDAP server connections',
        '/mga/server_connections/ldap/v1')


def istype(mixed):
    """
    Check if the given argument is a type object.

    :param mixed:
    :return: bool
    """
    return isinstance(mixed, type)


def uniform(x, y, u, v, scaling_factor):
    """
    Apply an uniform scaling

    Parameters
    ----------
    x : 2d np.ndarray

    y : 2d np.ndarray

    u : 2d np.ndarray

    v : 2d np.ndarray

    scaling_factor : float
        the image scaling factor in pixels per meter

    Return
    ----------
    x : 2d np.ndarray

    y : 2d np.ndarray

    u : 2d np.ndarray

    v : 2d np.ndarray

    """
    return (x / scaling_factor, y / scaling_factor, u / scaling_factor, v /
        scaling_factor)


def mun2i_NH3_NH3_CO3_CB89(T, P):
    """n-n-a: ammonia ammonia carbonate [CB89]."""
    mun2i = 0.000625
    valid = T == 298.15
    return mun2i, valid


def parse_facet(facet_int):
    """Convert an integer representing a facet into a tuple of its elements.

    Polyhedron facets in the MCNP input are represented as integers. Each digit
    represents the index of a vertex. For instance, the integer 1256
    represents the facet bounded by vertices 1, 2, 5 and 6.

    This function converts the integer representation into a tuple of indices,
    which is more convenient to work with. For example:

    >>> parse_facet(1256)
    (0, 1, 4, 5)

    Note that the resulting indices are zero-based, which is more suitable for
    Python.

    Zeros are ignored:

    >>> parse_facet(5230)
    (4, 1, 2)
    >>> parse_facet(7024)
    (6, 1, 3)

    :param int facet_int: the integer representing the facets
    :returns: a tuple of indices
    :rtype: tuple(int)
    """
    indices = []
    while facet_int != 0:
        facet_int, digit = divmod(facet_int, 10)
        facet_int, digit = int(facet_int), int(digit)
        if digit != 0:
            indices.append(digit - 1)
    return tuple(reversed(indices))


def _replace_multiple(main_string, replace_string, replace_with_string):
    """Replace a string with a list of substrings."""
    for elem in replace_string:
        if elem in main_string:
            main_string = main_string.replace(elem, replace_with_string)
    return main_string


@classmethod
def get_offset(cls, field_name):
    """Shorthand for self.get_type().get_offset(field_name)."""
    return cls.get_type().get_offset(field_name)


def edge_loops_from_tessfaces(mesh, tessfaces=None, seams=()):
    """
    Edge loops defined by faces

    Takes me.tessfaces or a list of faces and returns the edge loops
    These edge loops are the edges that sit between quads, so they dont touch
    1 quad, note: not connected will make 2 edge loops,
    both only containing 2 edges.

    return a list of edge key lists
    [[(0, 1), (4, 8), (3, 8)], ...]

    :arg mesh: the mesh used to get edge loops from.
    :type mesh: :class:`bpy.types.Mesh`
    :arg tessfaces: optional face list to only use some of the meshes faces.
    :type tessfaces: :class:`bpy.types.MeshTessFace`, sequence or or NoneType
    :return: return a list of edge vertex index lists.
    :rtype: list
    """
    OTHER_INDEX = 2, 3, 0, 1
    if tessfaces is None:
        tessfaces = mesh.tessfaces
    edges = {}
    for f in tessfaces:
        if len(f.vertices) == 4:
            edge_keys = f.edge_keys
            for i, edkey in enumerate(f.edge_keys):
                edges.setdefault(edkey, []).append(edge_keys[OTHER_INDEX[i]])
    for edkey in seams:
        edges[edkey] = []
    edge_loops = []
    for edkey, ed_adj in edges.items():
        if 0 < len(ed_adj) < 3:
            context_loop = [edkey, ed_adj[0]]
            edge_loops.append(context_loop)
            if len(ed_adj) == 2:
                other_dir = ed_adj[1]
            else:
                other_dir = None
            del ed_adj[:]
            flipped = False
            while 1:
                ed_adj = edges[context_loop[-1]]
                if len(ed_adj) != 2:
                    if other_dir and flipped is False:
                        flipped = True
                        context_loop.reverse()
                        del ed_adj[:]
                        context_loop.append(other_dir)
                        ed_adj = edges[context_loop[-1]]
                        if len(ed_adj) != 2:
                            del ed_adj[:]
                            break
                    else:
                        del ed_adj[:]
                        break
                i = ed_adj.index(context_loop[-2])
                context_loop.append(ed_adj[not i])
                del ed_adj[:]
    return edge_loops


def merge_dicts(*dicts):
    """Shallow copy and merge any number of input dicts.

    Precedence goes to key value pairs in latter dicts.

    Parameters
    ----------
    dicts : dict1, dict2, ...
        Any sequence of dict objects to merge.

    Examples
    --------
    >>> from secml.utils import merge_dicts

    >>> d1 = {'attr1': 100, 'attr2': 200}
    >>> d2 = {'attr3': 300, 'attr1': 999}  # Redefining `attr1`

    >>> merge_dicts(d1, d2)  # Value of `attr1` will be set according to `d2` dictionary
    {'attr3': 300, 'attr2': 200, 'attr1': 999}

    """
    result = {}
    for dict_i in dicts:
        result.update(dict_i)
    return result


@staticmethod
def _parse_lsb_release_content(lines):
    """
        Parse the output of the lsb_release command.

        Parameters:

        * lines: Iterable through the lines of the lsb_release output.
                 Each line must be a unicode string or a UTF-8 encoded byte
                 string.

        Returns:
            A dictionary containing all information items.
        """
    props = {}
    for line in lines:
        line = line.decode('utf-8') if isinstance(line, bytes) else line
        kv = line.strip('\n').split(':', 1)
        if len(kv) != 2:
            continue
        k, v = kv
        props.update({k.replace(' ', '_').lower(): v.strip()})
    return props


def keys(key=None):
    """Return an iterator over the keys in the container.

        If ``None`` is passed as `key`, this method behaves as if no argument
        were passed; exactly as required for ``IContainer.keys()``.

        If `key` is in the container, the first key provided by the iterator
        will be that key.  Otherwise, the first key will be the one that would
        come next if `key` were in the container.
        """


def extractCredentials(request):
    """Ties to extract credentials from a request.

        A return value of None indicates that no credentials could be found.
        Any other return value is treated as valid credentials.
        """


def importConnFromExcel(fileName, sheetName):
    """ Import connectivity rules from Excel sheet"""
    import openpyxl as xl
    colPreTags = 0
    colPostTags = 1
    colConnFunc = 2
    colSyn = 3
    colProb = 5
    colWeight = 6
    colAnnot = 8
    outFileName = fileName[:-5] + '_' + sheetName + '.py'
    connText = """## Generated using importConnFromExcel() function in params/utils.py

netParams['connParams'] = []

"""
    wb = xl.load_workbook(fileName)
    sheet = wb.get_sheet_by_name(sheetName)
    numRows = sheet.get_highest_row()
    with open(outFileName, 'w') as f:
        f.write(connText)
        for row in range(1, numRows + 1):
            if sheet.cell(row=row, column=colProb).value:
                print('Creating conn rule for row ' + str(row))
                pre = sheet.cell(row=row, column=colPreTags).value
                post = sheet.cell(row=row, column=colPostTags).value
                func = sheet.cell(row=row, column=colConnFunc).value
                syn = sheet.cell(row=row, column=colSyn).value
                prob = sheet.cell(row=row, column=colProb).value
                weight = sheet.cell(row=row, column=colWeight).value
                line = "netParams['connParams'].append({'preConds': {"
                for i, cond in enumerate(pre.split(';')):
                    if i > 0:
                        line = line + ', '
                    cond2 = cond.split('=')
                    line = line + "'" + cond2[0].replace(' ', ''
                        ) + "': " + cond2[1].replace(' ', '')
                line = line + '}'
                line = line + ",\n'postConds': {"
                for i, cond in enumerate(post.split(';')):
                    if i > 0:
                        line = line + ', '
                    cond2 = cond.split('=')
                    line = line + "'" + cond2[0].replace(' ', ''
                        ) + "': " + cond2[1].replace(' ', '')
                line = line + '}'
                line = line + ",\n'connFunc': '" + func + "'"
                line = line + ",\n'synMech': '" + syn + "'"
                line = line + ",\n'probability': " + str(prob)
                line = line + ",\n'weight': " + str(weight)
                line = line + '})'
                line = line + '\n\n'
                f.write(line)


def readcsv_numpy(csvfile):
    """
    Read CSV into a numpy array
    """
    import numpy
    return numpy.genfromtxt(csvfile, names=True, delimiter=',')


def nodeid(node):
    """Given a node, tries to return a way to see where it was in the
    source text"""
    fname = 'UNKNOWN'
    line = 'UNKNOWN'
    try:
        if node.line:
            line = str(node.line)
    except:
        pass
    try:
        if node.source:
            fname = str(node.source)
    except:
        pass
    return 'near line %s in file %s' % (line, fname)


@staticmethod
def is_actionable(media_file):
    """Perform check to determine if action should be taken.

        :param media_file: an instance of a MediaFile to check
        :returns: a flag indicating to act or not to act
        :rtype: boolean
        """
    return media_file.compressed


def _parse_qsub_job_id(qsub_out):
    """Parse job id from qsub output string.

    Assume format:

        "Your job <job_id> ("<job_name>") has been submitted"

    """
    return int(qsub_out.split()[2])


def _set_work_to_play(params, name: str, index: int, value: float):
    """Adjust the Parameters.work_to_play parameter"""
    if index is not None:
        raise IndexError('You cannot index the work_to_play parameter')
    params.work_to_play = value


def stitch_matched_regions(cigartuples):
    """
    Close gaps that are created by I or D events in cigar tuples.

    :param cigartuples:
    :return:
    >>> stitch_matched_regions([(4, 90), (0, 15), (1, 1), (0, 19)])
    [(4, 90), (0, 35)]
    >>> stitch_matched_regions([(4, 90), (0, 15), (1, 1), (0, 19), (5, 30)])
    [(4, 90), (0, 35), (5, 30)]
    >>> stitch_matched_regions([(4, 90), (0, 15), (2, 1), (0, 21)])
    [(4, 90), (0, 35)]
    >>> stitch_matched_regions([(4, 90), (0, 15), (1, 10), (0, 19)])
    [(4, 90), (0, 15), (1, 10), (0, 19)]
    >>> stitch_matched_regions([(4, 90), (0, 15), (2, 1), (0, 21), (7, 5)])  # Test that we don't produce an index error.
    [(4, 90), (0, 35)]
    >>> stitch_matched_regions([(1, 90), (0, 15), (1, 1), (0, 19)])
    [(0, 35)]
    """
    new_tuples = []
    for i, (op, l) in enumerate(cigartuples):
        if op in {1, 2, 7, 8}:
            if new_tuples and new_tuples[-1][0] == 0 and len(cigartuples
                ) != i + 1 and cigartuples[i + 1][0] == 0:
                previous_tuple = new_tuples.pop()
                add_length = previous_tuple[1]
                next_tuple = cigartuples.pop(i + 1)
                if op == 1:
                    add_length += l
                if op == 2:
                    add_length -= l
                if l < (next_tuple[1] + add_length) / 10.0:
                    cigartuples.insert(i + 1, (next_tuple[0], next_tuple[1] +
                        add_length))
                else:
                    new_tuples.append(previous_tuple)
                    new_tuples.append((op, l))
                    cigartuples.insert(i + 1, next_tuple)
        else:
            new_tuples.append((op, l))
    return new_tuples


def round_grid(value, grid, mode=0):
    """Round off the given value to the given grid size.

    Arguments:
    value -- value to be roudne
    grid -- result must be a multiple of this
    mode -- 0 nearest, 1 up, -1 down

    Examples:

    >>> round_grid(7.5, 5)
    10

    >>> round_grid(7.5, 5, mode=-1)
    5

    >>> round_grid(7.3, 5, mode=1)
    10

    >>> round_grid(7.3, 5.0, mode=1)
    10.0

    """
    off_grid = value % grid
    if mode == 0:
        add_one = int(off_grid >= grid / 2.0)
    elif mode == 1 and off_grid:
        add_one = 1
    elif mode == -1 and off_grid:
        add_one = 0
    result = (int(value / grid) + add_one) * grid
    return result


@staticmethod
def from_columns(columns, column_names=None, wrapped=True):
    """
        Build a new object of the type corresponding to the wrapper from the supplied `columns` (a list of columns).

        `column_names` supplies names of the columns (only relevant for :class:`Table2DWrapper`).
        If ``wrapped==True``, return a new wrapper contating the table; otherwise, just return the table.
        """
    raise NotImplementedError('I2DWrapper.from_columns')


def update_job_queue(jobQueue=None, state=None, priority=None,
    computeEnvironmentOrder=None):
    """
    Updates a job queue.
    See also: AWS API Documentation

    Examples
    This example disables a job queue so that it can be deleted.
    Expected Output:

    :example: response = client.update_job_queue(
        jobQueue='string',
        state='ENABLED'|'DISABLED',
        priority=123,
        computeEnvironmentOrder=[
            {
                'order': 123,
                'computeEnvironment': 'string'
            },
        ]
    )

    :type jobQueue: string
    :param jobQueue: [REQUIRED]
            The name or the Amazon Resource Name (ARN) of the job queue.

    :type state: string
    :param state: Describes the queue's ability to accept new jobs.

    :type priority: integer
    :param priority: The priority of the job queue. Job queues with a higher priority (or a lower integer value for the priority parameter) are evaluated first when associated with same compute environment. Priority is determined in ascending order, for example, a job queue with a priority value of 1 is given scheduling preference over a job queue with a priority value of 10 .

    :type computeEnvironmentOrder: list
    :param computeEnvironmentOrder: Details the set of compute environments mapped to a job queue and their order relative to each other. This is one of the parameters used by the job scheduler to determine which compute environment should execute a given job.
            (dict) --The order in which compute environments are tried for job placement within a queue. Compute environments are tried in ascending order. For example, if two compute environments are associated with a job queue, the compute environment with a lower order integer value is tried for job placement first.
            order (integer) -- [REQUIRED]The order of the compute environment.
            computeEnvironment (string) -- [REQUIRED]The Amazon Resource Name (ARN) of the compute environment.

    :rtype: dict
    :return: {
        'jobQueueName': 'string',
        'jobQueueArn': 'string'
    }

    """
    pass


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


def get_top_k_edges(method_ranks, k):
    """
    Return the top k edges for a given method.

    Args:
        method_ranks (pandas.Series): edges ranks for a given method, where each
            element represents the rank of a given edge
        k (int): top k edges to select

    Returns:
        list: list of the top k edges

    Example:
        >>> import pandas as pd
        >>> method_ranks = pd.Series([1,4,2,3], index=['gene1_gene2',
                                                       'gene1_gene3',
                                                       'gene3_gene1',
                                                       'gene3_gene2'])
        >>> edges = get_top_k_edges(method_ranks,2)
        >>> edges
        ['gene1_gene2', 'gene3_gene1']

    """
    return list(method_ranks.sort_values().index)[:k]


def open_hook(player, container, block):
    """
        The ``player`` is a Player's protocol
        The ``container`` is a 0x64 message
        The ``block`` is a block we trying to open
        :returns: ``Deffered`` with None or window object
        """
    pass


@classmethod
def convert(cls, value):
    """
        Normalize the provided value, or raise a :py:exc:`ValueError`.

        Values are assigned based on the case-insensitive prefix that
        they represent. `value` must be a string.
        """
    cvalue = value.casefold()
    for e in cls:
        if e.value.startswith(cvalue):
            return e
    else:
        raise ValueError(f'Illegal value of {cls.__name__} {value!r}')


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

    https://stackoverflow.com/a/20793663

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

    Returns
    -------
    TODO
        TODO

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


def format_seconds(total_seconds: float, *, precision: int=None) ->str:
    """
    Formats a number of seconds into meaningful units.

    If precision is specified as an int, then only this many of the largest
    non-zero units will be output in the string. Else, all will::

        >>> age = datetime.utcnow() - user.created_at
        >>> age_string = format_seconds(age.total_seconds(), precision=3)
        >>> print(age_string)
        33 days, 14 minutes, 12 seconds

    """
    mins, secs = divmod(total_seconds, 60)
    hrs, mins = divmod(mins, 60)
    days, hrs = divmod(hrs, 24)
    months, days = divmod(days, 30)
    years, months = divmod(months, 12)
    fmt = (lambda n, word: n and
        f"{n:.0f} {word}{int(n) - 1 and 's' or ''}" or '')
    queue = [fmt(years, 'year'), fmt(months, 'month'), fmt(days, 'day'),
        fmt(hrs, 'hour'), fmt(mins, 'minute'), fmt(secs, 'second')]
    queue = [*filter(None, queue)]
    if precision:
        queue = queue[:precision]
    return ', '.join(queue) or 'just now'


def remove_empty(iter_of_dicts):
    """Remove empty dictionaries from an iterable of dicts

    :param iter_of_dicts: iterable of dicts
    :return: iterable with empty dicts removed
    """
    return filter(lambda x: len(x) > 0, iter_of_dicts)


def _depgrep_node_label_use_action(_s, _l, tokens):
    """
    Returns the node label used to begin a tgrep_expr_labeled.  See
    `_depgrep_segmented_pattern_action`.

    Called for expressions like (`tgrep_node_label_use`)::

        =s

    when they appear as the first element of a `tgrep_expr_labeled`
    expression (see `_depgrep_segmented_pattern_action`).

    It returns the node label.
    """
    assert len(tokens) == 1
    assert tokens[0].startswith('=')
    return tokens[0][1:]


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

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

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


def openFile(segments, flags, mode):
    """
        Return a file object for `segments`.

        `flags` and `mode` are used for os.open function.
        """


def is_build_tag(tag: str) ->bool:
    """
    Test if the given *tag* looks like one of our build tags.
    """
    return tag.startswith('build-')


def humanize_speed(c_per_sec):
    """convert a speed in counts per second to counts per [s, min, h, d], choosing the smallest value greater zero.
    """
    scales = [60, 60, 24]
    units = ['c/s', 'c/min', 'c/h', 'c/d']
    speed = c_per_sec
    i = 0
    if speed > 0:
        while speed < 1 and i < len(scales):
            speed *= scales[i]
            i += 1
    return '{:.1f}{}'.format(speed, units[i])


@classmethod
def is_valid_transition(cls, from_value, to_value):
    """ Will check if to_value is a valid transition from from_value. Returns true if it is a valid transition.
        :param from_value: Start transition point
        :param to_value: End transition point
        :type from_value: int
        :type to_value: int
        :return: Success flag
        :rtype: bool
        """
    try:
        return from_value == to_value or from_value in cls.transition_origins(
            to_value)
    except KeyError:
        return False


def getInvoiceAddress():
    """Returns the invoice address.
        """


def subtract(timeaware, daterange=None):
    """ Returns a ITimeAware instance of time entries with the ones provided by the ITimeAware subtracted
        """


def mirror_distance_image(focal_point, distance_object):
    """Usage: Find distance of image with focal point and distance of object"""
    numerator = focal_point * distance_object
    denominator = distance_object - focal_point
    return numerator / denominator


def _is_header_line(line):
    """Determines if line represents the headers for the nodetool status
    output.

    """
    return line.startswith('-- ')


@staticmethod
def setup_command_line(parser):
    """Setup the command line options for Counting Principle formula

        Arguments:
        - `parser`: parser to load with options.
        """
    parser.add_argument('M', metavar='<M>', type=int, help='domain size')
    parser.add_argument('p', metavar='<p>', type=int, help='size of the parts')


def _calculate_check_digit(character_values):
    """
    Computes the check digit based on a modulus 103 checksum,
    the algorithm is quite simple, the idea is to weight the
    value of each position over its own index position.

    :type character_values: List
    :param character_values: The list of character values to
    calculate the check digit (checksum).
    :rtype: int
    :return: The resulting check digit for the provided set
    of character values.
    """
    checksum = character_values[0]
    remaining_values = character_values[1:]
    remaining_values_length = len(remaining_values)
    for index in range(remaining_values_length):
        value = remaining_values[index]
        weighted_value = value * (index + 1)
        checksum += weighted_value
    check_digit = checksum % 103
    return check_digit


def dict_replace(subject_dict, string):
    """
    Replace a dict map, key to its value in the stirng
    :param subject_dict: dict
    :param string: string
    :return: string
    """
    for i, j in subject_dict.items():
        string = string.replace(i, j)
    return string


def replaceScore(x):
    """
    Replace score to 0 if the type is string.
    """
    try:
        new_x = float(x)
    except:
        new_x = str(x)
    if type(new_x) == str:
        return 0
    else:
        return new_x


def expand_hparams(hparams):
    """
    Construct the training script args from the hparams
    """
    cmd = ''
    for field, val in hparams.items():
        if type(val) is bool:
            if val is True:
                cmd += '--{} '.format(field)
        elif val != 'None':
            cmd += '--{} {} '.format(field, val)
    cmd += "'"
    return cmd


def seq(hub, low, running):
    """
    Process the multi stage routine to determine the current requisite sequence
    """
    ret = hub.idem.req.seq.straight.run(low, running)
    ret = hub.idem.req.seq.prereq.run(ret, low, running)
    return ret


@staticmethod
def get_opt(opt_name, args):
    """Return option name and value.

        :param opt_name: name of the option, e.g., "username"
        :param args: parsed arguments
        """
    return opt_name, getattr(args, 'os_%s' % opt_name, None)


@staticmethod
def read_sorted_int(buf, offset):
    """
        Reads a sorted packed integer at the given buffer offset and returns it.

        :param buf: the buffer to read from.
        :type buf: bytearray
        :param offset: the offset in the buffer at which to start reading.
        :type offset: int
        :returns: the integer that was read.
        :rtype: int
        """
    b1 = buf[offset] & 255
    offset += 1
    if b1 < 8:
        byte_len = 8 - b1
        negative = True
    elif b1 > 247:
        byte_len = b1 - 247
        negative = False
    else:
        return b1 - 127
    """
        The following bytes on the buf store the value as a big endian integer.
        We extract the significant bytes from the buf and put them into the
        value in big endian order.
        """
    if negative:
        value = -1
    else:
        value = 0
    if byte_len > 3:
        value = value << 8 | buf[offset] & 255
        offset += 1
    if byte_len > 2:
        value = value << 8 | buf[offset] & 255
        offset += 1
    if byte_len > 1:
        value = value << 8 | buf[offset] & 255
        offset += 1
    value = value << 8 | buf[offset] & 255
    offset += 1
    """
        After get the adjusted value, we have to adjust it back to the original
        value.
        """
    if negative:
        value -= 119
    else:
        value += 121
    return value


def grouper(iterable, n, fillvalue=None):
    """Collect data into fixed-length chunks or blocks"""
    args = [iter(iterable)] * n
    while True:
        l = []
        try:
            for x in args:
                l.append(next(x))
        except Exception:
            pass
        yield l
        if len(l) < n:
            break


@staticmethod
def dict_initialise(metadata, analysistype):
    """
        Initialise dictionaries for storing DNA and amino acid sequences
        :param metadata: Metadata object
        :param analysistype: Current analysis type
        :return: Updated metadata
        """
    for sample in metadata:
        sample[analysistype].dnaseq = dict()
        sample[analysistype].protseq = dict()
        sample[analysistype].ntindex = dict()
        sample[analysistype].aaindex = dict()
        sample[analysistype].ntalign = dict()
        sample[analysistype].aaalign = dict()
        sample[analysistype].aaidentity = dict()
    return metadata


def load_host_keys(filename):
    """
    Read a file of known SSH host keys, in the format used by openssh, and
    return a compound dict of ``hostname -> keytype ->`` `PKey
    <paramiko.pkey.PKey>`. The hostname may be an IP address or DNS name.  The
    keytype will be either ``"ssh-rsa"`` or ``"ssh-dss"``.

    This type of file unfortunately doesn't exist on Windows, but on posix,
    it will usually be stored in ``os.path.expanduser("~/.ssh/known_hosts")``.

    Since 1.5.3, this is just a wrapper around `.HostKeys`.

    :param str filename: name of the file to read host keys from
    :return:
        nested dict of `.PKey` objects, indexed by hostname and then keytype
    """
    from paramiko.hostkeys import HostKeys
    return HostKeys(filename)


def _format_field_name(attr):
    """Format an object attribute in a human-friendly way."""
    parts = attr.rsplit(':', 1)
    name = parts[-1].replace('_', ' ')
    if name.isupper() or name.islower():
        name = name.title()
    parts[-1] = name
    return ': '.join(parts)


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


def __getitem__(username):
    """
        Get item by user login name or raise KeyError;
        result should provide IPropertiedUser
        """


@staticmethod
def find_python():
    """Searches default python which is first found in PATH"""
    from subprocess import check_output
    out = check_output(['which', 'python3']).decode('ascii').strip()
    if not out:
        out = check_output(['which', 'python2']).decode('ascii').strip()
    if not out:
        out = check_output(['which', 'python']).decode('ascii').strip()
    return out


def pb(D_eq):
    """Pruppacher and Beard Drop Shape relationship model.

    Implementation of the Pruppacher and Beard Drop Shape model given in [1]
    . This gives the ratio of the semi minor to semi major axis.

    Parameters
    -----------
    D_eq: float
        Volume Equivalent Drop Diameter

    Returns
    -------
    axis_ratio: float
        The ratio of the major to minor axis.

    See Also
    --------
    tb : Thurai and Bringi DSR
    bc : Beard and Chuang DSR
    brandes: Brandes DSR

    References
    ----------
    ..[1] Pruppacher, H. R. and Beard, K. V. (1970), A wind tunnel
      investigation of the internal circulation and shape of water drops
      falling at terminal velocity in air. Q.J.R. Meteorol. Soc., 96:
      247-256
    """
    return 1.03 - 0.062 * D_eq


@classmethod
def perform_mutation(cls, root, info, **data):
    """Perform the mutation.

        This should be implemented in subclasses to perform the mutation.
        """
    raise NotImplementedError


@staticmethod
def matcher_strong_literal(token, terminal, m):
    """ Check whether the meaning matches a strong literal terminal,
            i.e. one that is enclosed in double quotes ("dæmi:hk") """
    return terminal.matches_first(m.ordfl, m.stofn, token.t1_lower)


@classmethod
def set_shared_blockchain_instance(cls, instance):
    """ This method allows us to override default instance for all
            users of ``SharedInstance.instance``.

            :param chaininstance instance: Chain instance
        """
    cls._sharedInstance.instance = instance


def _justo_antes_de_simular(símismo):
    """
        Esta función, aplicada en las subclases de Simulable, efectua acciones necesarias una vez antes de cada
        simulación de cada experimento. Esto implica cosas que dependen en, por ejemplo, los valores de los parámetros
        de la simulación actual, pero que solamente necesitan hacerse una vez al principio de la simulación. Un ejemplo
        sería la inicialización de las poblaciones iniciales de organismos con poblaciones fijas en Redes según el valor
        del parámetro del tamaño de población fija.
        """
    raise NotImplementedError


def is_android_raw(raw):
    """
    Returns a string that describes the type of file, for common Android
    specific formats
    """
    val = None
    if raw[0:2] == b'PK' and b'AndroidManifest.xml' in raw:
        val = 'APK'
    elif raw[0:3] == b'dex':
        val = 'DEX'
    elif raw[0:3] == b'dey':
        val = 'DEY'
    elif raw[0:4] == b'\x03\x00\x08\x00' or raw[0:4] == b'\x00\x00\x08\x00':
        val = 'AXML'
    elif raw[0:4] == b'\x02\x00\x0c\x00':
        val = 'ARSC'
    return val


def setloadwarning(warn):
    """Assign a default for whether warnings should be shown when loading
    Initially, this is set to True
    """
    global _LDRWARN
    _LDRWARN = warn


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

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

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


def __getattr__(cls, item):
    """Special warning for attribute errors.

        Its likely that user may have wanted to use a model interface
        instead of the Base class.
        """
    raise AttributeError("'{}' has no attribute '{}'".format(cls.__name__,
        item))


def get_auth(host, app_name, database_name):
    """
    Authentication hook to allow plugging in custom authentication credential providers
    """
    from .hooks import _get_auth_hook
    return _get_auth_hook(host, app_name, database_name)


def GetPointsAtRadius(arr_shape, x, y, r):
    """Create a binary image of a circle radius r"""
    w, h = arr_shape
    r2 = int(r ** 2)
    l = []
    for i in range(int(x - r), int(x + r + 1)):
        for j in range(int(y - r), int(y + r + 1)):
            if (i - x) ** 2 + (j - y) ** 2 < r2:
                if 0 <= i < w and 0 <= j < h:
                    l += [[i, j]]
    return l


@classmethod
def from_xml(cls, node):
    """
        Construct a Symbol from a ``<symbol>`` XML node in EAGLE's XML format.
        """
    name = node.attrib['name']
    primitives = cls.geometry_from_xml(node)
    return cls(name=name, primitives=primitives)


def is_bool(x):
    """Tests if something is a boolean."""
    return isinstance(x, bool)


def hash_code(data):
    """Generate hash code using builtin hash() function.

    :param data: Data to generate hash code for
    """
    return abs(hash(data))


def namebunch(abunch, aname):
    """give the bunch object a name, if it has a Name field"""
    if abunch.Name == None:
        pass
    else:
        abunch.Name = aname
    return abunch


def processArgs(parser, args):
    """
    Essentially performs the function of a shell wrt string processing.

    All arguments that are enclosed with in " or ' are concatinated with a space
    before handing it off to the parser for processing.
    """
    allsplit = []
    if type(args) == str:
        allsplit = args.split()
    elif type(args) == list:
        allsplit = args
    else:
        raise Exception('Input args must be either a list or a str. (%s)' %
            type(args))
    retArgs = []
    appendStr = lambda x, y: ' '.join([x, y.strip('"').strip()]).strip()
    while len(allsplit) > 0:
        try:
            s = allsplit.pop(0).strip()
        except:
            break
        if s.startswith('"'):
            argString = ''
            while not s.endswith('"'):
                argString = appendStr(argString, s)
                try:
                    s = allsplit.pop(0).strip()
                except:
                    break
            argString = appendStr(argString, s)
            retArgs.append(argString)
        else:
            retArgs.append(s)
    try:
        return parser.parse_args(retArgs)
    except SystemExit:
        return None


def queryId(ob, default=None):
    """Get a unique id of an object.

        Return the default if the object isn't registered
        """


def wjoin(f, *insidef):
    """Calls self.vfs.reljoin(self.root, f, *insidef)"""


def split(path):
    """Split a path into (head, tail) pair.

    This function splits a path into a pair (head, tail) where 'tail' is
    the last pathname component and 'head' is all preceding components.

    Arguments:
        path (str): Path to split

    Returns:
        (str, str): a tuple containing the head and the tail of the path.

    Example:
        >>> split("foo/bar")
        ('foo', 'bar')
        >>> split("foo/bar/baz")
        ('foo/bar', 'baz')
        >>> split("/foo/bar/baz")
        ('/foo/bar', 'baz')

    """
    if '/' not in path:
        return '', path
    split = path.rsplit('/', 1)
    return split[0] or '/', split[1]


def _build_merge_vcf_command_str(raw_vcf_path_list):
    """Generate command string to merge vcf files into single multisample vcf."""
    command = ' '.join(['bcftools merge', ' '.join(raw_vcf_path_list)])
    return command


def bool_to_str(value: bool) ->str:
    """Converts boolean to 'ON' or 'OFF' string."""
    if type(value) is bool:
        return 'ON' if value is True else 'OFF'
    else:
        raise Exception(
            f"bool_to_str: unsupported variable type '{type(value)}', value '{value}'. Only boolean values are supported."
            )


def counter(items):
    """
    Simplest required implementation of collections.Counter. Required as 2.6
    does not have Counter in collections.
    """
    results = {}
    for item in items:
        results[item] = results.get(item, 0) + 1
    return results


def _is_substitution(content, start, end):
    """This is to support non-ARM-style direct parameter string substitution as a
    simplification of the concat function. We may wish to remove this
    if we want to adhere more strictly to ARM.
    :param str content: The contents of an expression from the template.
    :param int start: The start index of the expression.
    :param int end: The end index of the expression.
    """
    return not (content[start - 1] == '"' and content[end + 1] == '"')


def xy_to_id(x: int, y: int, nelx: int, nely: int, order: str='F') ->int:
    """
    Map from 2D indices of a node to the flattened 1D index.

    The number of elements is (nelx x nely), and the number of nodes is
    (nelx + 1) x (nely + 1).

    Parameters
    ----------
    x:
        The x-coordinate of the node's positions.
    y:
        The y-coordinate of the node's positions.
    nelx:
        The number of elements in the x-direction.
    nely:
        The number of elements in the y-direction.
    order:
        The order of indecies. "F" for Fortran/column-major order and "C" for
        C/row-major order.

    Returns
    -------
        The index of the node in the flattened version.

    """
    if order == 'C':
        return y * (nelx + 1) + x
    else:
        return x * (nely + 1) + y


def get_node_by_name(graph, name):
    """Return a node ID given its name."""
    for id, attrs in graph.nodes(data=True):
        if attrs['n'] == name:
            return id


def read_varint(stream):
    """Read while the most significant bit is set, then put the 7 least
    significant bits of all read bytes together to create a number.

    """
    value = 0
    while True:
        byte = ord(stream.read(1))
        if not byte & 128:
            return value << 7 | byte
        value = value << 7 | byte & 127


def divide_dict(a_dict, divide_func):
    """Divide a dict like object into two parts.

    - a_dict: dict like object
    - divide_func: the divide function to return True/False

    Return two parts of the dict.

    Example:
    divide({'a': 1, 'b': 2}, lambda k, v: v > 1)   ->   {'b': 2}, {'a': 1}
    """
    suit, not_suit = {}, {}
    for key, value in a_dict.items():
        result = suit if divide_func(key, value) else not_suit
        result[key] = value
    return suit, not_suit


@classmethod
def parse(cls, name, data_size, reader, parsers):
    """given a 4 byte name, data_size int, BitstreamReader
        and dict of {"atom":handler} sub-parsers,
        returns an atom of this class"""
    assert name == b'ftyp'
    return cls(reader.read_bytes(4), reader.read(32), [reader.read_bytes(4) for
        i in range((data_size - 8) // 4)])


@staticmethod
def p_record_layout_optional_list_optional(p):
    """record_layout_optional_list_optional : empty
                                                | record_layout_optional_list"""
    p[0] = tuple() if p[1] is None else p[1]


def siemens2rads(in_file, out_file=None):
    """
    Converts input phase difference map to rads
    """
    import numpy as np
    import nibabel as nb
    import os.path as op
    import math
    if out_file is None:
        fname, fext = op.splitext(op.basename(in_file))
        if fext == '.gz':
            fname, _ = op.splitext(fname)
        out_file = op.abspath('./%s_rads.nii.gz' % fname)
    in_file = np.atleast_1d(in_file).tolist()
    im = nb.load(in_file[0])
    data = im.get_data().astype(np.float32)
    hdr = im.header.copy()
    if len(in_file) == 2:
        data = nb.load(in_file[1]).get_data().astype(np.float32) - data
    elif data.ndim == 4 and data.shape[-1] == 2:
        data = np.squeeze(data[..., 1] - data[..., 0])
        hdr.set_data_shape(data.shape[:3])
    imin = data.min()
    imax = data.max()
    data = 2.0 * math.pi * (data - imin) / (imax - imin) - math.pi
    hdr.set_data_dtype(np.float32)
    hdr.set_xyzt_units('mm')
    hdr['datatype'] = 16
    nb.Nifti1Image(data, im.affine, hdr).to_filename(out_file)
    return out_file


def tokenizeRelationship(rel):
    """Returns a token for the given relationship"""


def check_perm_cycles(perm, operation):
    """
    This function checks the cycles in a given permutation according to the provided operation order and type.
    It counts the legal and illegal cycles in the permutation
    :param perm:
    :param op_order:
    :param op_type:
    :return: the number of illegal cycles, the number of molecules in illegal cycles, a dictionary of cycle lengths-
    with key =length cycle, val= mnumber of cycles of that length, and an array of the indices in bad cycles
    """
    op_order = operation.order
    op_type = operation.type
    checked = [False] * len(perm)
    num_molecules_in_bad_cycles = 0
    num_good_cycles = 0
    num_bad_cycles = 0
    cycle_counts = {}
    indices_in_bad_cycles = []
    for i, index in enumerate(perm):
        if checked[i]:
            continue
        checked[i] = True
        cycle = [index]
        while not checked[index]:
            checked[index] = True
            index = perm[index]
            cycle.append(index)
        cycle_len = len(cycle)
        if cycle_len in cycle_counts:
            cycle_counts[cycle_len] += 1
        else:
            cycle_counts[cycle_len] = 1
        if (cycle_len == 1 or cycle_len == op_order or cycle_len == 2 and
            op_type == 'SN'):
            num_good_cycles += 1
        else:
            num_molecules_in_bad_cycles += cycle_len
            num_bad_cycles += 1
            indices_in_bad_cycles += cycle
    return (num_bad_cycles, num_molecules_in_bad_cycles, cycle_counts,
        indices_in_bad_cycles)