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

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

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


def extended_cigar(aligned_template, aligned_query):
    """ Convert mutation annotations to extended cigar format

   https://github.com/lh3/minimap2#the-cs-optional-tag

   USAGE:
      >>> template = 'CGATCGATAAATAGAGTAG---GAATAGCA'
      >>> query = 'CGATCG---AATAGAGTAGGTCGAATtGCA'
      >>> extended_cigar(template, query) == ':6-ata:10+gtc:4*at:3'
      True
   """
    insertion = []
    deletion = []
    matches = []
    cigar = []
    for r_aa, q_aa in zip(aligned_template.lower(), aligned_query.lower()):
        gap_ref = r_aa == '-'
        gap_que = q_aa == '-'
        match = r_aa == q_aa
        if matches and not match:
            cigar.append(':%s' % len(matches))
            matches = []
        if insertion and not gap_ref:
            cigar.append('+%s' % ''.join(insertion))
            insertion = []
        elif deletion and not gap_que:
            cigar.append('-%s' % ''.join(deletion))
            deletion = []
        if gap_ref:
            if insertion:
                insertion.append(q_aa)
            else:
                insertion = [q_aa]
        elif gap_que:
            if deletion:
                deletion.append(r_aa)
            else:
                deletion = [r_aa]
        elif match:
            if matches:
                matches.append(r_aa)
            else:
                matches = [r_aa]
        else:
            cigar.append('*%s%s' % (r_aa, q_aa))
    if matches:
        cigar.append(':%s' % len(matches))
        del matches
    if insertion:
        cigar.append('+%s' % ''.join(insertion))
        del insertion
    elif deletion:
        cigar.append('-%s' % ''.join(deletion))
        del deletion
    return ''.join(cigar)


def parse_args(args):
    """Decodes UTF-8 encoded argument values.

    Parameters
    ----------
    args : dict
        Maps arbitrary keys to UTF-8 encoded strings / byte-arrays

    Returns
    -------
    dict
        Maps keys from args to decoded strings
    """
    rv = {}
    for key in args:
        rv[key] = []
        for value in args[key]:
            rv[key].append(value.decode(encoding='UTF-8'))
    return rv


@classmethod
def _dump_elf(cls, buf):
    """
        Dump the symbol table of an ELF file.
        Needs pyelftools (https://github.com/eliben/pyelftools)
        """
    from elftools.elf.elffile import ELFFile
    from elftools.elf import descriptions
    from io import BytesIO
    f = ELFFile(BytesIO(buf))
    print('ELF file:')
    for sec in f.iter_sections():
        if sec['sh_type'] == 'SHT_SYMTAB':
            symbols = sorted(sec.iter_symbols(), key=lambda sym: sym.name)
            print('    symbols:')
            for sym in symbols:
                if not sym.name:
                    continue
                print('    - %r: size=%d, value=0x%x, type=%s, bind=%s' % (
                    sym.name.decode(), sym['st_size'], sym['st_value'],
                    descriptions.describe_symbol_type(sym['st_info']['type'
                    ]), descriptions.describe_symbol_bind(sym['st_info'][
                    'bind'])))
    print()


@classmethod
def import_declaration_module(cls):
    """ Do the python import for the Declaration of the model or other
        """


def lint_citations(tool_xml, lint_ctx):
    """Ensure tool contains at least one valid citation."""
    root = tool_xml.getroot()
    citations = root.findall('citations')
    if len(citations) > 1:
        lint_ctx.error(
            'More than one citation section found, behavior undefined.')
        return
    if len(citations) == 0:
        lint_ctx.warn(
            'No citations found, consider adding citations to your tool.')
        return
    valid_citations = 0
    for citation in citations[0]:
        if citation.tag != 'citation':
            lint_ctx.warn(
                'Unknown tag discovered in citations block [%s], will be ignored.'
                 % citation.tag)
            continue
        citation_type = citation.attrib.get('type')
        if citation_type not in ('bibtex', 'doi'):
            lint_ctx.warn(
                'Unknown citation type discovered [%s], will be ignored.',
                citation_type)
            continue
        if citation.text is None or not citation.text.strip():
            lint_ctx.error('Empty %s citation.' % citation_type)
            continue
        valid_citations += 1
    if valid_citations > 0:
        lint_ctx.valid('Found %d likely valid citations.', valid_citations)


@classmethod
def ensure_indexes(cls):
    """
        Check&create if needed the Document's indexes in database
        """
    if cls.opts.indexes:
        cls.collection.create_indexes(cls.opts.indexes)


def gform(number, significant_digits=3):
    """
    Pretty print floating point numbers.

    Align floating point numbers at the decimal dot.

    ::

      |  -d.dde+xxx|
      |  -d.dde+xx |
      |-ddd.       |
      | -dd.d      |
      |  -d.dd     |
      |  -0.ddd    |
      |  -0.0ddd   |
      |  -0.00ddd  |
      |  -d.dde-xx |
      |  -d.dde-xxx|
      |         nan|

    The formatted string has length ``significant_digits * 2 + 6``.
    """
    no_exp_range = pow(10.0, -1), pow(10.0, significant_digits)
    width = significant_digits + significant_digits - 1 + 1 + 1 + 5
    if no_exp_range[0] <= abs(number) < no_exp_range[1] or number == 0.0:
        s = ('%#.*g' % (significant_digits, number)).rstrip('0')
    else:
        s = '%.*E' % (significant_digits - 1, number)
    s = (' ' * (-s.find('.') + (significant_digits + 1)) + s).ljust(width)
    if s.strip().lower() == 'nan':
        s = 'nan'.rjust(width)
    return s


def printed(o, **kwargs):
    """Print an object and return it"""
    return print(o, **kwargs) or o


@classmethod
def _get_dma(cls, df):
    """ Different of Moving Average

        default to 10 and 50.
        :param df: data
        :return: None
        """
    df['dma'] = df['close_10_sma'] - df['close_50_sma']


@staticmethod
def find_site_url(soup, url: str) ->str:
    """
        Attempts to find the canonical Url of the Site

        :param soup: BeautifulSoup of site
        :param url: Current Url of site
        :return: str
        """
    canonical = soup.find(name='link', rel='canonical')
    try:
        site = canonical.get('href')
        if site:
            return site
    except AttributeError:
        pass
    meta = soup.find(name='meta', property='og:url')
    try:
        site = meta.get('content')
    except AttributeError:
        return url
    return site


def find(symbs, allsymbs):
    """
Sort elements in symbs according to allsymbs to form and return (args, inds)
with list of ordered arguments as args and corresponding list of indices in
allsymbs as inds.
    """
    args = []
    inds = []
    n = 0
    for symb in allsymbs:
        if symb in symbs:
            args.append(symb)
            inds.append(n)
        n += 1
    return tuple(args), tuple(inds)


def quickjoin_join_pivots(S1, S2, distance, radius):
    """
    From Fredriksson & Braithwaite. Algorithm 5.

    """
    N1 = len(S1)
    N2 = len(S2)
    k = max(1, min(16, N1 // 8))
    P = [0] * N2 * k
    for i in range(k):
        A = S1[i]
        for j in range(N2):
            B = S2[j]
            d = distance(A, B)
            P[i * N2 + j] = d
            if d <= radius:
                yield A, B
    D = [0] * k
    for i in range(k, N1):
        A = S1[i]
        for l in range(k):
            D[l] = distance(S1[l], A)
        for j in range(N2):
            B = S2[j]
            f = False
            for l in range(k):
                if abs(P[l * N2 + j] - D[l]) > radius:
                    f = True
                    break
            if not f and distance(A, B) <= radius:
                yield A, B


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 chunks(list_, count_items_in_chunk):
    """
    разбить list (l) на куски по n элементов

    :param list_:
    :param count_items_in_chunk:
    :return:
    """
    for i in range(0, len(list_), count_items_in_chunk):
        yield list_[i:i + count_items_in_chunk]


def objectItems(spec=None):
    """List (ID, subobject) tuples for subobjects of the current object.

        If 'spec' is specified, returns only objects whose meta_types match
        'spec'.
        """


def describe_fleet_capacity(FleetIds=None, Limit=None, NextToken=None):
    """
    Retrieves the current status of fleet capacity for one or more fleets. This information includes the number of instances that have been requested for the fleet and the number currently active. You can request capacity for all fleets, or specify a list of one or more fleet IDs. When requesting multiple fleets, use the pagination parameters to retrieve results as a set of sequential pages. If successful, a  FleetCapacity object is returned for each requested fleet ID. When specifying a list of fleet IDs, attribute objects are returned only for fleets that currently exist.
    See also: AWS API Documentation

    :example: response = client.describe_fleet_capacity(
        FleetIds=[
            'string',
        ],
        Limit=123,
        NextToken='string'
    )

    :type FleetIds: list
    :param FleetIds: Unique identifier for a fleet(s) to retrieve capacity information for. To request capacity information for all fleets, leave this parameter empty.
            (string) --

    :type Limit: integer
    :param Limit: Maximum number of results to return. Use this parameter with NextToken to get results as a set of sequential pages. This parameter is ignored when the request specifies one or a list of fleet IDs.

    :type NextToken: string
    :param NextToken: Token that indicates the start of the next sequential page of results. Use the token that is returned with a previous call to this action. To specify the start of the result set, do not specify a value. This parameter is ignored when the request specifies one or a list of fleet IDs.

    :rtype: dict
    :return: {
        'FleetCapacity': [
            {
                'FleetId': 'string',
                'InstanceType': 't2.micro'|'t2.small'|'t2.medium'|'t2.large'|'c3.large'|'c3.xlarge'|'c3.2xlarge'|'c3.4xlarge'|'c3.8xlarge'|'c4.large'|'c4.xlarge'|'c4.2xlarge'|'c4.4xlarge'|'c4.8xlarge'|'r3.large'|'r3.xlarge'|'r3.2xlarge'|'r3.4xlarge'|'r3.8xlarge'|'m3.medium'|'m3.large'|'m3.xlarge'|'m3.2xlarge'|'m4.large'|'m4.xlarge'|'m4.2xlarge'|'m4.4xlarge'|'m4.10xlarge',
                'InstanceCounts': {
                    'DESIRED': 123,
                    'MINIMUM': 123,
                    'MAXIMUM': 123,
                    'PENDING': 123,
                    'ACTIVE': 123,
                    'IDLE': 123,
                    'TERMINATING': 123
                }
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


def _calc_feather_weighting(param_dict):
    """
    Calculate weightings to use for the feather task
    """
    weightings = param_dict['weightings']
    if not isinstance(weightings, (list, tuple)):
        return 1.0
    return float(weightings[1]) / float(weightings[0])


def getPeerCertificate():
    """
        Return an object with the peer's certificate info.
        """


def decode_polyline(polyline):
    """Decodes a Polyline string into a list of lat/lng dicts.

    See the developer docs for a detailed description of this encoding:
    https://developers.google.com/maps/documentation/utilities/polylinealgorithm

    :param polyline: An encoded polyline
    :type polyline: string

    :rtype: list of dicts with lat/lng keys
    """
    points = []
    index = lat = lng = 0
    while index < len(polyline):
        result = 1
        shift = 0
        while True:
            b = ord(polyline[index]) - 63 - 1
            index += 1
            result += b << shift
            shift += 5
            if b < 31:
                break
        lat += ~result >> 1 if result & 1 != 0 else result >> 1
        result = 1
        shift = 0
        while True:
            b = ord(polyline[index]) - 63 - 1
            index += 1
            result += b << shift
            shift += 5
            if b < 31:
                break
        lng += ~(result >> 1) if result & 1 != 0 else result >> 1
        points.append({'lat': lat * 1e-05, 'lng': lng * 1e-05})
    return points


@classmethod
def add_common_opts(cls, parser):
    """Add options that are common for several plugins."""
    for opt in cls.common_opt_names:
        cls._parser_add_opt(parser, opt)


def QSettings_writeArrayItem(settings, key, index, item, arraysize=-1):
    """
    Write/update an array item at index.

    Parameters
    ----------
    settings : QSettings
    key : str
    index : int
    item : Dict[str, Any]
    arraysize : int
        The full array size. Note that the array will be truncated to this
        size.
    """
    if arraysize < 0:
        arraysize = settings.beginReadArray(key)
        settings.endArray()
    settings.beginWriteArray(key, arraysize)
    settings.setArrayIndex(index)
    for key_, val in item.items():
        settings.setValue(key_, val)
    settings.endArray()


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

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


def del1col(me, xid):
    """delete one col with transparent index mapping."""
    me._colmap.del1(xid, me._del_cols)


def _get_beta_example(var, mbf_sets, field, i):
    """Internal beta function calculator"""
    return 1.0 / (1.0 + (((var - mbf_sets[field]['m'][i]) / mbf_sets[field]
        ['a'][i]) ** 2) ** mbf_sets[field]['b'][i])


def uch_leung(us, ut):
    """
    Choking velocity based on Equation 6 from Leung [2]_. All parameters must
    be in units of ft/s or in units of m/s.

    Parameters
    ----------
    us : float
        Solids velocity [ft/s or m/s]
    ut : float
        Terminal velocity of a single particle [ft/s or m/s]

    Returns
    -------
    uch : float
        Choking velocity [ft/s or m/s]

    References
    ----------
    .. [2] L.S. Leung, Robert J. Wiles, and Donald J. Nicklin. Correlation for
       Predicting Choking Flowrates in Vertical Pneumatic Conveying. Ind. Eng.
       Chem. Process Des. Develop., vol. 10, no. 2, pp. 183-189, 1971.
    """
    uch = 32.3 * us + 0.97 * ut
    return uch


def generate_batches(num_records, batch_size):
    """Generate batch size list for splitting a number of tasks into batch jobs.

    Given a number of records to split up, and a batch size, generate a
    stream of batchsize, index pairs"""
    num_batches = num_records // batch_size + 1
    for i in range(0, num_batches):
        if i == num_batches - 1:
            batch_size = num_records - batch_size * i
        if batch_size > 0:
            yield batch_size, i


def isoformat(dt):
    """Return iso-formatted timestamp

    Like .isoformat(), but uses Z for UTC instead of +00:00
    """
    return dt.isoformat().replace('+00:00', 'Z')


def GetIndex(header):
    """

    Returns the height/index of a header

    """
    pass


@staticmethod
def make_index_var(w):
    """ Embellish the variable name if the user is checking the option
         by its index in the options array."""
    return '_i_' + w


def __new__(cls, *args, **keyargs):
    """
        Does not allow you to create an instance.
        """
    raise Exception("Cannot create an instance of '%s' class" % cls.__name__)


def close():
    """
        Release resources (sockets) held by this object.

        .. versionadded:: 3.0
        """


def envmap_clear_all():
    """Discard all environment maps in the .blend file and free them from memory

    """
    pass


def group_deselect():
    """Deselect bones of active Bone Group

    """
    pass


@staticmethod
def oracle_all_sequences(_dal):
    """
        Oracle specific: List all sequences in an Oracle database

        :param _dal: A connected instance of DatabaseAbstractionLayer (see qal.dal)
        :return: A list or sequence names
        """
    if not _dal.connected:
        _dal.connect_to_db()
    rows = _dal.query('SELECT SEQUENCE_NAME FROM USER_SEQUENCES')
    sequences = list()
    for row in rows:
        sequences.append(row[0])
    return sequences


def get_flags(xds_table_obj, corr=None, chan=slice(0, None)):
    """ Get Flag values from the FLAG column. Allow for selections in the channel dimension or the correlation dimension

    Parameters
    ----------
    corr : :obj:`int`
        Correlation number to select.
    xds_table_obj : :obj:`xarray.Dataset`
        MS as xarray dataset from xarrayms

    Returns
    -------
    flags : :obj:`xarray.DataArray`
        Data array containing values from FLAG column selected by correlation if index is available.

    """
    flags = xds_table_obj.FLAG
    if corr is None:
        return flags.sel(chan=chan)
    else:
        flags = flags.sel(dict(corr=corr, chan=chan))
    return flags


@classmethod
def read(cls, filename: str) ->'HipsSurveyProperties':
    """Read from HiPS survey description file (`HipsSurveyProperties`).

        Parameters
        ----------
        filename : str
            HiPS properties filename
        """
    with open(filename) as fh:
        text = fh.read()
    return cls.parse(text)


@staticmethod
def CleanupRightHandSide(s):
    """
        Remove spaces, leading +

        >>> EquationParser.CleanupRightHandSide(' +x')
        'x'

        :return: str
        """
    s = s.strip()
    if len(s) == 0:
        return s
    if s[0] == '+':
        s = s[1:]
    return s


def stabilityParam(L_m, siteConf):
    """
    Calculates the Monin-Obukhov Similarity Variable
    defined as

    zeta = (z-d)/Lo
    where d is the displacement height or zero-plane displacement
    and L_m is the Monin-Obukhov Length.
    """
    z = siteConf.measurement_height
    d = siteConf.displacement_height
    zeta = (z - d) / L_m
    return zeta


def flip_layers(nparray):
    """
    Flip RGB to BGR image data (numpy ndarray).
    Also accepts rgbA/bgrA and single channel images without crashing.
    """
    if nparray is None:
        return None
    if len(nparray.shape) == 3:
        if nparray.shape[2] == 4:
            return nparray[..., [2, 1, 0, 3]]
        else:
            return nparray[:, :, ::-1]
    return nparray


@staticmethod
def calc_network(address, mask):
    """
        Calculate the network address from the set IP address and subnet mask.
        :param address: IP address
        :param mask: subnet mask
        :return: network address
        """
    addr_splitter = address.split('.')
    mask_splitter = mask.split('.')
    network_arr = []
    for i in range(0, len(addr_splitter)):
        network_arr.append(str(int(addr_splitter[i]) & int(mask_splitter[i])))
    return '.'.join(network_arr)


@staticmethod
def operations(nsteps):
    """Returns the number of operations needed for nsteps of CG"""
    return {'A': 1 + nsteps, 'M': 2 + nsteps, 'Ml': 2 + nsteps, 'Mr': 1 +
        nsteps, 'ip_B': 2 + 2 * nsteps, 'axpy': 2 + 2 * nsteps}


def array_from_header(header):
    """Convert header information to array parameters.

    :Parameters:

    header : header_dtype
             Header fields

    :Returns:

    header : dict
             File header
    dtype : dtype
            Data type
    shape : tuple
            Shape of the array
    order : str
            Order of the array
    offset : int
             Header offset
    swap : bool
            Swap byte order
    """
    pass


@classmethod
def _days_to_seconds(cls, val, **kwargs):
    """
        converts a number of days to seconds
        """
    zero_value = kwargs.get('zero_value', 0)
    if val is not None:
        if val == 0:
            return zero_value
        return val * 86400
    else:
        return 'Not Defined'


def falstart_print(message, error=False, prefix='[falstart] >'):
    """ Display given message with prefix"""
    bold, red, end = '\x1b[1m', '\x1b[31m', '\x1b[0m'
    print(''.join((red if error else '', bold, prefix, end, red if error else
        '', ' ', message, end)).strip())


def get_doc():
    """Get documentation of this resource

    :return: rst string
    :rtype: str
    """
    return """
    The ``command`` model is used to represent a command in the monitored system.

    A command is used:

    - for the hosts and services active checks. The command is a check plugin
    used to determine the host or service state.

    - for the event handlers launched when an host / service state changes.

     - for the notifications sent to inform the users of the detected problems
    """


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

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

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


def check_csrf_token(request, token):
    """ Determine if the supplied ``token`` is valid. Most implementations
        should simply compare the ``token`` to the current value of
        ``get_csrf_token`` but it is possible to verify the token using
        any mechanism necessary using this method.

        Returns ``True`` if the ``token`` is valid, otherwise ``False``.

        """


def msisdn_to_whatsapp(msisdn):
    """ Convert an MSISDN to a WhatsApp address. """
    return msisdn.lstrip('+') + '@s.whatsapp.net'


@classmethod
def where_ip(cls, ip):
    """ Get db model by username """
    return cls.query.filter_by(ip=ip).first()


@staticmethod
def _get_out(waterbody, datetime_time_step, dict_data_frame,
    c_out_c_no3_ove, c_out_c_nh4_ove, c_out_c_dph_ove, c_out_c_pph_ove,
    c_out_c_sed_ove, c_out_c_no3_dra, c_out_c_nh4_dra, c_out_c_dph_dra,
    c_out_c_pph_dra, c_out_c_sed_dra, c_out_c_no3_int, c_out_c_nh4_int,
    c_out_c_dph_int, c_out_c_pph_int, c_out_c_sed_int, c_out_c_no3_sgw,
    c_out_c_nh4_sgw, c_out_c_dph_sgw, c_out_c_pph_sgw, c_out_c_sed_sgw,
    c_out_c_no3_dgw, c_out_c_nh4_dgw, c_out_c_dph_dgw, c_out_c_pph_dgw,
    c_out_c_sed_dgw, c_out_c_no3, c_out_c_nh4, c_out_c_dph, c_out_c_pph,
    c_out_c_sed, c_s_c_no3_ove, c_s_c_nh4_ove, c_s_c_dph_ove, c_s_c_pph_ove,
    c_s_c_sed_ove, c_s_c_no3_dra, c_s_c_nh4_dra, c_s_c_dph_dra,
    c_s_c_pph_dra, c_s_c_sed_dra, c_s_c_no3_int, c_s_c_nh4_int,
    c_s_c_dph_int, c_s_c_pph_int, c_s_c_sed_int, c_s_c_no3_sgw,
    c_s_c_nh4_sgw, c_s_c_dph_sgw, c_s_c_pph_sgw, c_s_c_sed_sgw,
    c_s_c_no3_dgw, c_s_c_nh4_dgw, c_s_c_dph_dgw, c_s_c_pph_dgw,
    c_s_c_sed_dgw, c_s_c_no3_soil, c_s_c_nh4_soil, c_s_c_p_org_ra_soil,
    c_s_c_p_ino_ra_soil, c_s_m_p_org_fb_soil, c_s_m_p_ino_fb_soil,
    c_s_m_sed_soil):
    """
        This function is the interface between the model and the data models of the simulator.
        It stores the outputs, and updated states in the data frame.
        """
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_no3_ove'
        ] = c_out_c_no3_ove
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_nh4_ove'
        ] = c_out_c_nh4_ove
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_dph_ove'
        ] = c_out_c_dph_ove
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_pph_ove'
        ] = c_out_c_pph_ove
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_sed_ove'
        ] = c_out_c_sed_ove
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_no3_dra'
        ] = c_out_c_no3_dra
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_nh4_dra'
        ] = c_out_c_nh4_dra
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_dph_dra'
        ] = c_out_c_dph_dra
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_pph_dra'
        ] = c_out_c_pph_dra
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_sed_dra'
        ] = c_out_c_sed_dra
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_no3_int'
        ] = c_out_c_no3_int
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_nh4_int'
        ] = c_out_c_nh4_int
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_dph_int'
        ] = c_out_c_dph_int
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_pph_int'
        ] = c_out_c_pph_int
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_sed_int'
        ] = c_out_c_sed_int
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_no3_sgw'
        ] = c_out_c_no3_sgw
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_nh4_sgw'
        ] = c_out_c_nh4_sgw
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_dph_sgw'
        ] = c_out_c_dph_sgw
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_pph_sgw'
        ] = c_out_c_pph_sgw
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_sed_sgw'
        ] = c_out_c_sed_sgw
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_no3_dgw'
        ] = c_out_c_no3_dgw
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_nh4_dgw'
        ] = c_out_c_nh4_dgw
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_dph_dgw'
        ] = c_out_c_dph_dgw
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_pph_dgw'
        ] = c_out_c_pph_dgw
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_sed_dgw'
        ] = c_out_c_sed_dgw
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_no3'] = c_out_c_no3
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_nh4'] = c_out_c_nh4
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_dph'] = c_out_c_dph
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_pph'] = c_out_c_pph
    dict_data_frame[waterbody][datetime_time_step]['c_out_c_sed'] = c_out_c_sed
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_no3_ove'
        ] = c_s_c_no3_ove
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_nh4_ove'
        ] = c_s_c_nh4_ove
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_dph_ove'
        ] = c_s_c_dph_ove
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_pph_ove'
        ] = c_s_c_pph_ove
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_sed_ove'
        ] = c_s_c_sed_ove
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_no3_dra'
        ] = c_s_c_no3_dra
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_nh4_dra'
        ] = c_s_c_nh4_dra
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_dph_dra'
        ] = c_s_c_dph_dra
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_pph_dra'
        ] = c_s_c_pph_dra
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_sed_dra'
        ] = c_s_c_sed_dra
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_no3_int'
        ] = c_s_c_no3_int
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_nh4_int'
        ] = c_s_c_nh4_int
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_dph_int'
        ] = c_s_c_dph_int
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_pph_int'
        ] = c_s_c_pph_int
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_sed_int'
        ] = c_s_c_sed_int
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_no3_sgw'
        ] = c_s_c_no3_sgw
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_nh4_sgw'
        ] = c_s_c_nh4_sgw
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_dph_sgw'
        ] = c_s_c_dph_sgw
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_pph_sgw'
        ] = c_s_c_pph_sgw
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_sed_sgw'
        ] = c_s_c_sed_sgw
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_no3_dgw'
        ] = c_s_c_no3_dgw
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_nh4_dgw'
        ] = c_s_c_nh4_dgw
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_dph_dgw'
        ] = c_s_c_dph_dgw
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_pph_dgw'
        ] = c_s_c_pph_dgw
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_sed_dgw'
        ] = c_s_c_sed_dgw
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_no3_soil'
        ] = c_s_c_no3_soil
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_nh4_soil'
        ] = c_s_c_nh4_soil
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_p_org_ra_soil'
        ] = c_s_c_p_org_ra_soil
    dict_data_frame[waterbody][datetime_time_step]['c_s_c_p_ino_ra_soil'
        ] = c_s_c_p_ino_ra_soil
    dict_data_frame[waterbody][datetime_time_step]['c_s_m_p_org_fb_soil'
        ] = c_s_m_p_org_fb_soil
    dict_data_frame[waterbody][datetime_time_step]['c_s_m_p_ino_fb_soil'
        ] = c_s_m_p_ino_fb_soil
    dict_data_frame[waterbody][datetime_time_step]['c_s_m_sed_soil'
        ] = c_s_m_sed_soil


def report_copy():
    """Copy selected reports to Clipboard

    """
    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


def filter_log_events(logGroupName=None, logStreamNames=None, startTime=
    None, endTime=None, filterPattern=None, nextToken=None, limit=None,
    interleaved=None):
    """
    Lists log events from the specified log group. You can list all the log events or filter the results using a filter pattern, a time range, and the name of the log stream.
    By default, this operation returns as many log events as can fit in 1MB (up to 10,000 log events), or all the events found within the time range that you specify. If the results include a token, then there are more log events available, and you can get additional results by specifying the token in a subsequent call.
    See also: AWS API Documentation

    :example: response = client.filter_log_events(
        logGroupName='string',
        logStreamNames=[
            'string',
        ],
        startTime=123,
        endTime=123,
        filterPattern='string',
        nextToken='string',
        limit=123,
        interleaved=True|False
    )

    :type logGroupName: string
    :param logGroupName: [REQUIRED]
            The name of the log group.

    :type logStreamNames: list
    :param logStreamNames: Optional list of log stream names.
            (string) --

    :type startTime: integer
    :param startTime: The start of the time range, expressed as the number of milliseconds since Jan 1, 1970 00:00:00 UTC. Events with a timestamp prior to this time are not returned.

    :type endTime: integer
    :param endTime: The end of the time range, expressed as the number of milliseconds since Jan 1, 1970 00:00:00 UTC. Events with a timestamp later than this time are not returned.

    :type filterPattern: string
    :param filterPattern: The filter pattern to use. If not provided, all the events are matched.

    :type nextToken: string
    :param nextToken: The token for the next set of events to return. (You received this token from a previous call.)

    :type limit: integer
    :param limit: The maximum number of events to return. The default is 10,000 events.

    :type interleaved: boolean
    :param interleaved: If the value is true, the operation makes a best effort to provide responses that contain events from multiple log streams within the log group interleaved in a single response. If the value is false all the matched log events in the first log stream are searched first, then those in the next log stream, and so on. The default is false.

    :rtype: dict
    :return: {
        'events': [
            {
                'logStreamName': 'string',
                'timestamp': 123,
                'message': 'string',
                'ingestionTime': 123,
                'eventId': 'string'
            },
        ],
        'searchedLogStreams': [
            {
                'logStreamName': 'string',
                'searchedCompletely': True|False
            },
        ],
        'nextToken': 'string'
    }

    """
    pass


@classmethod
def decode(cls, data):
    """
        This method takes a bytes object which contains the raw content octets
        of the object. That means, the octets *without* the type information
        and length.

        This function must be overridden by the concrete subclasses.
        """
    raise NotImplementedError('Decoding is not yet implemented on %s' % cls)


def gap_remove(all: bool=False):
    """Remove gap at current frame to first strip at the right, independent of selection or locked state of strips

    :param all: All Gaps, Do all gaps to right of current frame
    :type all: bool
    """
    pass


def is_modified_terminal(v):
    """Check if v is a terminal or a terminal wrapped in terminal modifier types."""
    while not v._ufl_is_terminal_:
        if v._ufl_is_terminal_modifier_:
            v = v.ufl_operands[0]
        else:
            return False
    return True


def has_metadata(name):
    """Does the package's distribution contain the named metadata?"""


def get_record_set_values(resource_records):
    """
    @type resource_records: list
    """
    out = list()
    for record in resource_records:
        out.append(record.get('Value'))
    return out


@staticmethod
def colorRGB(r, g, b):
    """
        Given the R,G,B int values for the RGB color mode in the range [0..255],
        return a RGB color tuple with float values in the range [0..1].
        """
    return float(r / 255), float(g / 255), float(b / 255)


@classmethod
def on_configuration_finished(cls):
    """
    Callback function that is triggered, when the configuration of all undetected controllers is complete
    """
    print('EVENT:' + 'All controllers are configured')


def process_type_from_etype(etype):
    """Return the type of data process from etype name"""
    return etype[len('Data'):-len('Process')].lower()


def delete_subnet(DryRun=None, SubnetId=None):
    """
    Deletes the specified subnet. You must terminate all running instances in the subnet before you can delete the subnet.
    See also: AWS API Documentation

    Examples
    This example deletes the specified subnet.
    Expected Output:

    :example: response = client.delete_subnet(
        DryRun=True|False,
        SubnetId='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 SubnetId: string
    :param SubnetId: [REQUIRED]
            The ID of the subnet.

    :return: response = client.delete_subnet(
        SubnetId='subnet-9d4a7b6c',
    )

    print(response)

    """
    pass


@classmethod
def from_environ(cls, environ):
    """
        Deserialize an instance that was written to the environment via
        ``to_environ``.

        Parameters
        ----------
        environ : dict-like
            Dict-like object (e.g. os.environ) from which to read ``self``.
        """
    return cls.from_base64(environ[cls.__name__])


def primitive_square_add(size: float=100.0, location: float=(0.0, 0.0)):
    """Add new square-shaped spline

    :param size: Size, Size of new circle
    :type size: float
    :param location: Location, Location of new circle
    :type location: float
    """
    pass


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 _is_sunder(name):
    """Return True if a _sunder_ name, False otherwise."""
    return name[0] == name[-1] == '_' and name[1:2] != '_' and name[-2:-1
        ] != '_' and len(name) > 2


@staticmethod
def geocentric_position(helio_pos):
    """Compute the geocentric latitude (Theta) and longitude (beta) (in degrees) of the sun given the earth's heliocentric position (L, B, R)"""
    L, B, R = helio_pos
    th = L + 180
    b = -B
    return th, b


def _nominal_b0(val):
    """
    Infer Nominal Magnetic Field Strength from exact one.
    """
    val = float(val)
    if abs(round(val) - round(val, 1)) > 0:
        val = round(val, 1)
    else:
        val = int(round(val))
    return val


def trange(df, high, low, close, tr):
    """
    Welles Wilder described these calculations to determine the trading range
    for a stock or commodity. True Range is defined as the largest of the
    following:

    - The distance from today's high to today's low.
    - The distance from yesterday's close to today's high.
    - The distance from yesterday's close to today's low.

    Parameters:
        df (pd.DataFrame): DataFrame which contain the asset information.
        high (string): the column name for the period highest price  of the asset.
        low (string): the column name for the period lowest price of the asset.
        close (string): the column name for the closing price of the asset.
        tr (string): the column name for the tr values.

    Returns:
        df (pd.DataFrame): Dataframe with the true range calculated.

    """
    prev_close = df[close].shift(1)
    df['h-l'] = df[high] - df[low]
    df['h-pc'] = df[high] - prev_close
    df['pc-l'] = prev_close - df[low]
    df = df.dropna().reset_index(drop=True)
    df[tr] = df[['h-l', 'h-pc', 'pc-l']].max(axis=1)
    df.drop(['h-l', 'h-pc', 'pc-l'], axis=1, inplace=True)
    return df


@staticmethod
def _get_chan_labels(ibw_wave, codec='utf-8'):
    """
        Retrieves the names of the data channels and default units

        Parameters
        ----------
        ibw_wave : dictionary
            Wave entry in the dictionary obtained from loading the ibw file
        codec : str, optional
            Codec to be used to decode the bytestrings into Python strings if needed.
            Default 'utf-8'

        Returns
        -------
        labels : list of strings
            List of the names of the data channels
        default_units : list of strings
            List of units for the measurement in each channel
        """
    temp = ibw_wave.get('labels')
    labels = []
    for item in temp:
        if len(item) > 0:
            labels += item
    for item in labels:
        if item == '':
            labels.remove(item)
    default_units = list()
    for chan_ind, chan in enumerate(labels):
        if type(chan) == bytes:
            chan = chan.decode(codec)
        if chan.lower().rfind('trace') > 0:
            labels[chan_ind] = chan[:chan.lower().rfind('trace') + 5]
        else:
            labels[chan_ind] = chan
        if chan.startswith('Phase'):
            default_units.append('deg')
        elif chan.startswith('Current'):
            default_units.append('A')
        else:
            default_units.append('m')
    return labels, default_units


def force_list(data):
    """Wrap data in a tuple.

    Wraps its argument in a tuple so that it can be iterated over, unless
    it was a list, a tuple, or a set (therefore already iterable).

    Note that if ``data`` is ``None`` this method will return ``None``, which
    is not iterable.
    """
    if data is not None and not isinstance(data, (list, tuple, set)):
        return data,
    return data


def write(sim, name, attributes):
    """
    Write generic attributes of simulation and system to a file.

    `name` is a tag appended to `sim.base_path` to define the output
    file path.

    `attributes` must be a list of valid properties of the Simulation
    instance `sim` or of its System instance `sim.system`.
    """
    f = sim.output_path + '.' + name
    if sim.current_step == 0:
        with open(f, 'w') as fh:
            fh.write('# columns: %s\n' % ', '.join(attributes))
    else:
        values = []
        for attr in attributes:
            level = len(attr.split('.'))
            if level == 1:
                values.append(getattr(sim, attr))
            elif level == 2:
                system_attr = attr.split('.')[-1]
                if attr.startswith('system'):
                    values.append(getattr(sim.system, system_attr))
            else:
                raise ValueError('attribute is too deep')
        fmt = '%s ' * len(attributes) + '\n'
        with open(f, 'a') as fh:
            fh.write(fmt % tuple(values))


def error(message, code=-1):
    """Return an error with the specified message and code."""
    err = {'Error': message, 'Code': code}
    return err


@classmethod
def get(cls, consistent=False, **kwargs):
    """Get an item from the table

        Example::

            Thing.get(hash_key="three")

        :param bool consistent: If set to True the get will be a consistent read
        :param \\*\\*kwargs: You must supply your hash key, and range key if used, with the values to get
        """
    item = cls.Table.get(consistent=consistent, **kwargs)
    return cls.new_from_raw(item)


@classmethod
def create(cls, analysis_system):
    """
        Create a new `AnalysisSystemInstance` on the server.

        For convenience `AnalysisSystem.create_analysis_system_instance()` can be used instead.

        :param analysis_system: The corresponding `AnalysisSystem` object
        :return: The created `AnalysisSystemInstance` object
        """
    return cls._create(analysis_system=analysis_system.url)


def is_dict(obj):
    """ Check if the object is a dictionary. """
    return isinstance(obj, dict)


@classmethod
def get(cls, loadable):
    """return the include function and the root include object."""
    raise NotImplementedError


def compute_taxonomic_distance(ref_lineage: str, query_lineage: str):
    """
    Calculates the number of taxonomic ranks need to be climbed in the taxonomic hierarchy before a common ancestor
    is identified between the two taxa.
    If no common ancestor is reached, the distance is returned along with a status of 1 to indicate non-convergence.

    :param ref_lineage: A taxonomic lineage string, where each rank is separated by semi-colons (;)
    :param query_lineage: Another taxonomic lineage string, where each rank is separated by semi-colons (;)
    :return: Tuple of (distance, status)
    """
    distance = 0
    l1 = ref_lineage.split('; ')
    l2 = query_lineage.split('; ')
    try:
        while l1 != l2:
            if len(l1) > len(l2):
                l1 = l1[:-1]
            elif len(l2) > len(l1):
                l2 = l2[:-1]
            else:
                l2 = l2[:-1]
                l1 = l1[:-1]
            distance += 1
    except IndexError:
        return distance, 1
    return distance, 0


def convert_datetime_to_str(df, *, column: str, format: str, new_column:
    str=None):
    """
    Convert datetime column into string column

    ---

    ### Parameters

    *mandatory :*
    - column (*str*): name of the column to format
    - format (*str*): format of the result values (see [available formats](
    https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior))

    *optional :*
    - new_column (*str*): name of the output column. By default `column` is overwritten.
    """
    new_column = new_column or column
    df[new_column] = df[column].dt.strftime(format)
    return df


@classmethod
def validate(cls, obj, raise_errors=False):
    """Validate an object to check if it could be of this type.

        Args:
            obj (object): Object to validate.
            raise_errors (bool, optional): If True, errors will be raised when
                the object fails to be validated. Defaults to False.

        Returns:
            bool: True if the object could be of this type, False otherwise.

        """
    if not cls.python_types:
        raise NotImplementedError("Attribute 'python_types' must be set.")
    out = isinstance(obj, cls.python_types)
    if not out and raise_errors:
        raise ValueError(("Object of type '%s' is not one of the accepted " +
            'Python types (%s) for this type (%s).') % (type(obj), cls.
            python_types, cls.name))
    return out


def sizeof_fmt(bytes_size, forced_unit='B'):
    """
    Convert the size into a more human readable format.
    The final unit could be forced by the second param.
        :param bytes_size: Size to convert (in bytes)
        :param forced_unit='B': Output unit. Could be choosen between :
            B, KB, MB, GB, TB, PB, EB, ZB, KiB, MiB, GiB, TiB, PiB, EiB, ZiB

    Note : Inspired from
    https://web.archive.org/web/20111010015624/http://blogmag.net/blog/read/38/Print_human_readable_file_size # noqa #pylint: disable
    """
    forced_unit = forced_unit.lower()
    if 'i' in forced_unit:
        divisor = 1024.0
        units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB']
    else:
        divisor = 1000.0
        units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB']
    lower_units = map(str.lower, units)
    if forced_unit in lower_units or forced_unit == '':
        for unit in units:
            if abs(bytes_size
                ) < divisor and forced_unit == '' or forced_unit == unit.lower(
                ):
                if isinstance(bytes_size, int):
                    if bytes_size > 9007199254740992:
                        print(bytes_size)
                        raise ArithmeticError(
                            'The bytes_size variable (value : %s) is not convenient with IEEE754 standard. It is not a representable integer, that means it is upper than 2^54+1'
                             % bytes_size)
                return '%3.1f%s' % (bytes_size, unit)
            bytes_size /= divisor
    return '%.1f%s' % (bytes_size, 'B')


def slice_tracks(tracks, max_tracklist_length):
    """Return a (tracks, length) tuple, where tracks is the list of tracks with length
    less than or equal to max_tracklist_length and length is the length of tracks.
    """
    length = 0.0
    for i, track in enumerate(tracks):
        if length + track['length'] <= max_tracklist_length:
            length += track['length']
        else:
            break
    return tracks[:i + 1], length


def normalize_direction(direction_text):
    """
    returns the single letter corresponding to the input direction
    """
    return direction_text[0].upper()


def basic_unicode_escape(code_point):
    """
    Basic backslash-escape.  Useful for creating error messages, etc.
    """
    n = ord(code_point)
    if n <= 65535:
        return '\\u{0:04x}'.format(n)
    return '\\U{0:08x}'.format(n)


@staticmethod
def list_wrap(spec):
    """
        If not a list, wraps the spec in a list.
        """
    if not isinstance(spec, list):
        spec = [spec]
    return spec


@classmethod
def mkdtemp(cls, suffix='', prefix=''):
    """Creates a temporary directory in the file system

        Returns an instance representing the path to the new directory.

        Similar to Python's tempfile.mkdtemp, like that function the
        caller is responsible for cleaning up the directory, which can
        be done with :py:meth:`rmtree`."""
    raise NotImplementedError


def create_thing_type(thingTypeName=None, thingTypeProperties=None):
    """
    Creates a new thing type.
    See also: AWS API Documentation

    :example: response = client.create_thing_type(
        thingTypeName='string',
        thingTypeProperties={
            'thingTypeDescription': 'string',
            'searchableAttributes': [
                'string',
            ]
        }
    )

    :type thingTypeName: string
    :param thingTypeName: [REQUIRED]
            The name of the thing type.

    :type thingTypeProperties: dict
    :param thingTypeProperties: The ThingTypeProperties for the thing type to create. It contains information about the new thing type including a description, and a list of searchable thing attribute names.
            thingTypeDescription (string) --The description of the thing type.
            searchableAttributes (list) --A list of searchable thing attribute names.
            (string) --

    :rtype: dict
    :return: {
        'thingTypeName': 'string',
        'thingTypeArn': 'string'
    }

    """
    pass


def _analyze(doc, analyzer=None, tokenizer=None, ngrams=None, preprocessor=
    None, decoder=None, stop_words=None):
    """Chain together an optional series of text processing steps to go from
    a single document to ngrams, with or without tokenizing or preprocessing.

    If analyzer is used, only the decoder argument is used, as the analyzer is
    intended to replace the preprocessor, tokenizer, and ngrams steps.

    Parameters
    ----------
    analyzer: callable, default=None
    tokenizer: callable, default=None
    ngrams: callable, default=None
    preprocessor: callable, default=None
    decoder: callable, default=None
    stop_words: list, default=None

    Returns
    -------
    ngrams: list
        A sequence of tokens, possibly with pairs, triples, etc.
    """
    if decoder is not None:
        doc = decoder(doc)
    if analyzer is not None:
        doc = analyzer(doc)
    else:
        if preprocessor is not None:
            doc = preprocessor(doc)
        if tokenizer is not None:
            doc = tokenizer(doc)
        if ngrams is not None:
            if stop_words is not None:
                doc = ngrams(doc, stop_words)
            else:
                doc = ngrams(doc)
    return doc


def azion_cdn_rules():
    """
        Create default CDN Rules Engine config.
    """
    return [{'path': '/images/', 'regex': False, 'protocol_policy':
        'http,https', 'gzip': True, 'behavior': 'delivery',
        'path_origin_name': 'origin-static', 'cache_settings_name':
        'cache-1-hour-ignore-qs-cookies'}, {'path': '/fonts/', 'regex':
        False, 'protocol_policy': 'http,https', 'gzip': True, 'behavior':
        'delivery', 'path_origin_name': 'origin-static',
        'cache_settings_name': 'cache-1-hour-ignore-qs-cookies'}, {'path':
        '/css/', 'regex': False, 'protocol_policy': 'http,https', 'gzip':
        True, 'behavior': 'delivery', 'path_origin_name': 'origin-static',
        'cache_settings_name': 'cache-5-minutes-ignore-qs-cookies'}, {
        'path': '/js/', 'regex': False, 'protocol_policy': 'http,https',
        'gzip': True, 'behavior': 'delivery', 'path_origin_name':
        'origin-static', 'cache_settings_name':
        'cache-5-minutes-ignore-qs-cookies'}, {'path': '/proxy', 'regex':
        False, 'protocol_policy': 'http', 'gzip': True, 'behavior':
        'acceleration', 'path_origin_name': 'origin-proxy',
        'cache_settings_name': 'cache-bypass', 'forward_cookies': 'all'}, {
        'path': '/site', 'regex': False, 'protocol_policy': 'http', 'gzip':
        True, 'behavior': 'acceleration', 'path_origin_name':
        'origin-default', 'cache_settings_name': 'cache-bypass',
        'forward_cookies': 'all'}]


def duplicate_elements(vals, n):
    """
    takes list `vals` and duplicates each element `n` times
    (e.g., `n=1` will return `vals`)
    """
    return sum(map(list, zip(*[vals for _ in range(n)])), [])


def graph_select_border(gesture_mode: int=0, xmin: int=0, xmax: int=0, ymin:
    int=0, ymax: int=0, extend: bool=True):
    """Select curve points using border selection

    :param gesture_mode: Gesture Mode
    :type gesture_mode: int
    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    :param extend: Extend, Extend selection instead of deselecting everything first
    :type extend: bool
    """
    pass


@staticmethod
def compare_entropy(start_slice, end_slice, slice, difference):
    """ Calculate the entropy of two slices (from the start and end
            of an axis), returning a tuple containing the amount that
            should be added to the start, and removed from the end
            of that axis.

            Based on the eponymous function from easy-thumbnails:
                https://git.io/fhqpT
        """
    from instakit.utils.stats import histogram_entropy
    start_entropy = histogram_entropy(start_slice)
    end_entropy = histogram_entropy(end_slice)
    if end_entropy and abs(start_entropy / end_entropy - 1) < 0.01:
        if difference >= slice * 2:
            return slice, slice
        half_slice = slice // 2
        return half_slice, slice - half_slice
    if start_entropy > end_entropy:
        return 0, slice
    else:
        return slice, 0


@classmethod
def pad_move(cls, x, y):
    """
        Reorients where the top left of the PAD should be, so it knows which
        region to display to the user.

        :param x: the x element of the top left of the region to display
        :param y: the y element of the top left of the region to display
        """
    cls.PAD_X, cls.PAD_Y = x, y


def get_min_delta_mags(model):
    """Second smallest value minus smallest value of fitted Lomb Scargle model."""
    return model['min_delta_mags']


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

    The ".dev0" means dirty.

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


def strToBool(val):
    """
    Helper function to turn a string representation of "true" into
    boolean True.
    """
    if isinstance(val, str):
        val = val.lower()
    return val in ['true', 'on', 'yes', True]


def put_config_rule(ConfigRule=None):
    """
    Adds or updates an AWS Config rule for evaluating whether your AWS resources comply with your desired configurations.
    You can use this action for custom Config rules and AWS managed Config rules. A custom Config rule is a rule that you develop and maintain. An AWS managed Config rule is a customizable, predefined rule that AWS Config provides.
    If you are adding a new custom Config rule, you must first create the AWS Lambda function that the rule invokes to evaluate your resources. When you use the PutConfigRule action to add the rule to AWS Config, you must specify the Amazon Resource Name (ARN) that AWS Lambda assigns to the function. Specify the ARN for the SourceIdentifier key. This key is part of the Source object, which is part of the ConfigRule object.
    If you are adding an AWS managed Config rule, specify the rule's identifier for the SourceIdentifier key. To reference AWS managed Config rule identifiers, see About AWS Managed Config Rules .
    For any new rule that you add, specify the ConfigRuleName in the ConfigRule object. Do not specify the ConfigRuleArn or the ConfigRuleId . These values are generated by AWS Config for new rules.
    If you are updating a rule that you added previously, you can specify the rule by ConfigRuleName , ConfigRuleId , or ConfigRuleArn in the ConfigRule data type that you use in this request.
    The maximum number of rules that AWS Config supports is 50.
    For more information about requesting a rule limit increase, see AWS Config Limits in the AWS General Reference Guide .
    For more information about developing and using AWS Config rules, see Evaluating AWS Resource Configurations with AWS Config in the AWS Config Developer Guide .
    See also: AWS API Documentation

    :example: response = client.put_config_rule(
        ConfigRule={
            'ConfigRuleName': 'string',
            'ConfigRuleArn': 'string',
            'ConfigRuleId': 'string',
            'Description': 'string',
            'Scope': {
                'ComplianceResourceTypes': [
                    'string',
                ],
                'TagKey': 'string',
                'TagValue': 'string',
                'ComplianceResourceId': 'string'
            },
            'Source': {
                'Owner': 'CUSTOM_LAMBDA'|'AWS',
                'SourceIdentifier': 'string',
                'SourceDetails': [
                    {
                        'EventSource': 'aws.config',
                        'MessageType': 'ConfigurationItemChangeNotification'|'ConfigurationSnapshotDeliveryCompleted'|'ScheduledNotification'|'OversizedConfigurationItemChangeNotification',
                        'MaximumExecutionFrequency': 'One_Hour'|'Three_Hours'|'Six_Hours'|'Twelve_Hours'|'TwentyFour_Hours'
                    },
                ]
            },
            'InputParameters': 'string',
            'MaximumExecutionFrequency': 'One_Hour'|'Three_Hours'|'Six_Hours'|'Twelve_Hours'|'TwentyFour_Hours',
            'ConfigRuleState': 'ACTIVE'|'DELETING'|'DELETING_RESULTS'|'EVALUATING'
        }
    )

    :type ConfigRule: dict
    :param ConfigRule: [REQUIRED]
            The rule that you want to add to your account.
            ConfigRuleName (string) --The name that you assign to the AWS Config rule. The name is required if you are adding a new rule.
            ConfigRuleArn (string) --The Amazon Resource Name (ARN) of the AWS Config rule.
            ConfigRuleId (string) --The ID of the AWS Config rule.
            Description (string) --The description that you provide for the AWS Config rule.
            Scope (dict) --Defines which resources can trigger an evaluation for the rule. The scope can include one or more resource types, a combination of one resource type and one resource ID, or a combination of a tag key and value. Specify a scope to constrain the resources that can trigger an evaluation for the rule. If you do not specify a scope, evaluations are triggered when any resource in the recording group changes.
            ComplianceResourceTypes (list) --The resource types of only those AWS resources that you want to trigger an evaluation for the rule. You can only specify one type if you also specify a resource ID for ComplianceResourceId .
            (string) --
            TagKey (string) --The tag key that is applied to only those AWS resources that you want you want to trigger an evaluation for the rule.
            TagValue (string) --The tag value applied to only those AWS resources that you want to trigger an evaluation for the rule. If you specify a value for TagValue , you must also specify a value for TagKey .
            ComplianceResourceId (string) --The IDs of the only AWS resource that you want to trigger an evaluation for the rule. If you specify a resource ID, you must specify one resource type for ComplianceResourceTypes .
            Source (dict) -- [REQUIRED]Provides the rule owner (AWS or customer), the rule identifier, and the notifications that cause the function to evaluate your AWS resources.
            Owner (string) -- [REQUIRED]Indicates whether AWS or the customer owns and manages the AWS Config rule.
            SourceIdentifier (string) -- [REQUIRED]For AWS Config managed rules, a predefined identifier from a list. For example, IAM_PASSWORD_POLICY is a managed rule. To reference a managed rule, see Using AWS Managed Config Rules .
            For custom rules, the identifier is the Amazon Resource Name (ARN) of the rule's AWS Lambda function, such as arn:aws:lambda:us-east-1:123456789012:function:custom_rule_name .
            SourceDetails (list) --Provides the source and type of the event that causes AWS Config to evaluate your AWS resources.
            (dict) --Provides the source and the message types that trigger AWS Config to evaluate your AWS resources against a rule. It also provides the frequency with which you want AWS Config to run evaluations for the rule if the trigger type is periodic. You can specify the parameter values for SourceDetail only for custom rules.
            EventSource (string) --The source of the event, such as an AWS service, that triggers AWS Config to evaluate your AWS resources.
            MessageType (string) --The type of notification that triggers AWS Config to run an evaluation for a rule. You can specify the following notification types:
            ConfigurationItemChangeNotification - Triggers an evaluation when AWS Config delivers a configuration item as a result of a resource change.
            OversizedConfigurationItemChangeNotification - Triggers an evaluation when AWS Config delivers an oversized configuration item. AWS Config may generate this notification type when a resource changes and the notification exceeds the maximum size allowed by Amazon SNS.
            ScheduledNotification - Triggers a periodic evaluation at the frequency specified for MaximumExecutionFrequency .
            ConfigurationSnapshotDeliveryCompleted - Triggers a periodic evaluation when AWS Config delivers a configuration snapshot.
            If you want your custom rule to be triggered by configuration changes, specify both ConfigurationItemChangeNotification and OversizedConfigurationItemChangeNotification .
            MaximumExecutionFrequency (string) --The frequency that you want AWS Config to run evaluations for a custom rule with a periodic trigger. If you specify a value for MaximumExecutionFrequency , then MessageType must use the ScheduledNotification value.
            Note
            By default, rules with a periodic trigger are evaluated every 24 hours. To change the frequency, specify a valid value for the MaximumExecutionFrequency parameter.

            InputParameters (string) --A string in JSON format that is passed to the AWS Config rule Lambda function.
            MaximumExecutionFrequency (string) --The maximum frequency with which AWS Config runs evaluations for a rule. You can specify a value for MaximumExecutionFrequency when:
            You are using an AWS managed rule that is triggered at a periodic frequency.
            Your custom rule is triggered when AWS Config delivers the configuration snapshot. For more information, see ConfigSnapshotDeliveryProperties .
            Note
            By default, rules with a periodic trigger are evaluated every 24 hours. To change the frequency, specify a valid value for the MaximumExecutionFrequency parameter.
            ConfigRuleState (string) --Indicates whether the AWS Config rule is active or is currently being deleted by AWS Config. It can also indicate the evaluation status for the Config rule.
            AWS Config sets the state of the rule to EVALUATING temporarily after you use the StartConfigRulesEvaluation request to evaluate your resources against the Config rule.
            AWS Config sets the state of the rule to DELETING_RESULTS temporarily after you use the DeleteEvaluationResults request to delete the current evaluation results for the Config rule.
            AWS Config sets the state of a rule to DELETING temporarily after you use the DeleteConfigRule request to delete the rule. After AWS Config deletes the rule, the rule and all of its evaluations are erased and are no longer available.

    :returns:
    ConfigurationItemChangeNotification - Triggers an evaluation when AWS Config delivers a configuration item as a result of a resource change.
    OversizedConfigurationItemChangeNotification - Triggers an evaluation when AWS Config delivers an oversized configuration item. AWS Config may generate this notification type when a resource changes and the notification exceeds the maximum size allowed by Amazon SNS.
    ScheduledNotification - Triggers a periodic evaluation at the frequency specified for MaximumExecutionFrequency .
    ConfigurationSnapshotDeliveryCompleted - Triggers a periodic evaluation when AWS Config delivers a configuration snapshot.

    """
    pass


def provider_parser(subparser):
    """Configure provider parser for CloudNS"""
    identity_group = subparser.add_mutually_exclusive_group()
    identity_group.add_argument('--auth-id', help=
        'specify user id for authentication')
    identity_group.add_argument('--auth-subid', help=
        'specify subuser id for authentication')
    identity_group.add_argument('--auth-subuser', help=
        'specify subuser name for authentication')
    subparser.add_argument('--auth-password', help=
        'specify password for authentication')
    subparser.add_argument('--weight', help='specify the SRV record weight')
    subparser.add_argument('--port', help='specify the SRV record port')


def patch_if_none(obj, key, value):
    """If obj.get(key) is None, this runs obj[key] = value."""
    if obj.get(key) is None:
        obj[key] = value


def param_def(default=None, validator=None, doc=None, options=0, name=None,
    owner=None):
    """ Construct a complete parameter definition """
    return dict(default=default, validator=validator, doc=doc, options=
        options, name=name, owner=owner)


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

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


def reset_recent():
    """Reset Recent files

    """
    pass


def _overlap(x0, x1, y0, y1):
    """ do (x0, x1) and (y0, y1) overlap? """
    if x0 < y0:
        return x1 > y0
    return y1 > x0


def wait(time: int):
    """
    Pause the user program for a specified amount of time.

    ----------
    time : int - How long to wait in milliseconds
    """
    ...


def num_bps(paired_region):
    """Return number of base pairs (=Length) of paired_region

    paired_region -- PairedRegion object
    """
    return paired_region.Length


def str2dict(dotted_str, value=None, separator='.'):
    """ Convert dotted string to dict splitting by :separator: """
    dict_ = {}
    parts = dotted_str.split(separator)
    d, prev = dict_, None
    for part in parts:
        prev = d
        d = d.setdefault(part, {})
    else:
        if value is not None:
            prev[part] = value
    return dict_


def browse_interactive(pose_index: int=-1):
    """Interactively browse poses in 3D-View

    :param pose_index: Pose, Index of the pose to apply (-2 for no change to pose, -1 for poselib active pose)
    :type pose_index: int
    """
    pass


def _decrypt_cbc(algorithm, key, ciphertext, iv=None):
    """Decrypt the ciphertext and return the plaintext value."""
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import padding
    from cryptography.hazmat.primitives.ciphers import Cipher, modes
    from pskc.exceptions import DecryptionError
    if not iv:
        iv = ciphertext[:algorithm.block_size // 8]
        ciphertext = ciphertext[algorithm.block_size // 8:]
    cipher = Cipher(algorithm(key), modes.CBC(iv), backend=default_backend())
    decryptor = cipher.decryptor()
    unpadder = padding.PKCS7(algorithm.block_size).unpadder()
    try:
        return unpadder.update(decryptor.update(ciphertext) + decryptor.
            finalize()) + unpadder.finalize()
    except ValueError:
        raise DecryptionError('Invalid padding')


def delete(use_global: bool=False):
    """Delete selected objects

    :param use_global: Delete Globally, Remove object from all scenes
    :type use_global: bool
    """
    pass


@classmethod
def build_tag(cls, tag, text='', attrs=None):
    """Build tag full info include the attributes.

        :param tag: tag name.
        :param text: tag text.
        :param attrs: tag attributes. Default：``None``.
        :type attrs: dict or None
        :rtype: str
        """
    return '{}{}{}'.format(cls.tag_start(tag, attrs), text, cls.tag_end(tag))


def is_naive(value):
    """
    Determines if a given datetime.datetime is naive.

    The logic is described in Python's docs:
    http://docs.python.org/library/datetime.html#datetime.tzinfo
    """
    return value.tzinfo is None or value.tzinfo.utcoffset(value) is None


def init_parameters():
    """
	Initialize parameters
	"""
    global params
    params = dict()
    params['core'] = dict()
    params['ontology'] = dict()
    params['ac'] = dict()
    params['query'] = dict()
    params['ss'] = dict()
    params['stats'] = dict()
    params['output'] = dict()
    params['core']['program_dir'] = None
    params['core']['load_params'] = None
    params['core']['save_params'] = None
    params['core']['verbose'] = 1
    params['core']['inject_IC'] = None
    params['core']['task'] = None
    params['ontology']['ontology_file'] = None
    params['ontology']['ontology_type'] = None
    params['ontology']['ontology_file_format'] = None
    params['ontology']['ignore'] = list()
    params['ac']['ac'] = None
    params['ac']['ac_type'] = None
    params['ac']['ac_species'] = 'human'
    params['ac']['ac_file'] = None
    params['ac']['EC_include'] = list()
    params['ac']['EC_ignore'] = list()
    params['ac']['tax_include'] = list()
    params['ac']['tax_ignore'] = list()
    params['ac']['ac_multiple'] = None
    params['ac']['ac_separator'] = None
    params['ac']['ac_term_first'] = None
    params['query']['query_ss_type'] = None
    params['query']['query_mode'] = None
    params['query']['query_input'] = None
    params['query']['query_file_sep'] = '\t'
    params['query']['query_file'] = None
    params['ss']['ss_root'] = None
    params['ss']['use_enhanced'] = None
    params['ss']['tss_measure'] = None
    params['ss']['tss_mix'] = None
    params['output']['cut_thres'] = None
    params['output']['out_file'] = None
    params['output']['out_mode'] = 'console'
    params['output']['cut_nan'] = None
    params['stats']['IC'] = None
    return params


@staticmethod
def _serialize_io(io):
    """
        Helper method to serialize object's IO as ref

        :param io: :class:`ModelIO` instance
        :return: ref payload
        """
    io_type = type(io)
    return f'{io_type.__module__}.{io_type.__name__}'.encode('utf-8')


def do_reload_config(sc, args):
    """Trigger a config reload."""
    print(sc.reload_config()['message'])


def generateAcceptHeader(*elements):
    """Generate an accept header value

    [str or (str, float)] -> str
    """
    parts = []
    for element in elements:
        if type(element) is str:
            qs = '1.0'
            mtype = element
        else:
            mtype, q = element
            q = float(q)
            if q > 1 or q <= 0:
                raise ValueError('Invalid preference factor: %r' % q)
            qs = '%0.1f' % (q,)
        parts.append((qs, mtype))
    parts.sort()
    chunks = []
    for q, mtype in parts:
        if q == '1.0':
            chunks.append(mtype)
        else:
            chunks.append('%s; q=%s' % (mtype, q))
    return ', '.join(chunks)


def reinterpret_latin1_as_windows1252(wrongtext):
    """
    Maybe this was always meant to be in a single-byte encoding, and it
    makes the most sense in Windows-1252.
    """
    return wrongtext.encode('latin-1').decode('WINDOWS_1252', 'replace')


@classmethod
def distance(cls, point, curve):
    """点とカーブを与えるとその距離を返す"""
    return curve.distance(point)


def convert_error_code(error_code):
    """Convert error code from the format returned by pywin32 to the format that Microsoft documents everything in."""
    return error_code % 2 ** 32


def printsigdiffs(agg2):
    """Print significant differences in aggregated data for two summary
    data frames.
    """
    Xwinner = sum(agg2['XlessY'] > agg2['YlessX'])
    Ywinner = sum(agg2['XlessY'] < agg2['YlessX'])
    gr = agg2['XlessY'].size
    print('X is yielding more frequently better results on ', Xwinner,
        ' groups (', round(Xwinner / gr * 100, 2), '%)')
    print('Y is yielding more frequently better results on ', Ywinner,
        ' groups (', round(Ywinner / gr * 100, 2), '%)')
    print('\nSignificant differences:')
    sigXlessY = agg2[agg2.p_XlessY <= 0.05]
    sigYlessX = agg2[agg2.p_YlessX <= 0.05]
    if not sigXlessY.empty:
        print('\np_XlessY<=0.05\n', sigXlessY)
    if not sigYlessX.empty:
        print('\np_YlessX<=0.05\n', sigYlessX)


def p_postgap(t):
    """postgap : POSTGAP TIMESTAMP"""
    t[0] = 'postgap', t[2]


def coords_json_to_api_pos(x_cm_forward, y_cm_left):
    """converts from robot coordinates to API coordinates. returns x, y"""
    x_cm_right = -y_cm_left
    y_cm_forward = x_cm_forward
    return x_cm_right, y_cm_forward


@staticmethod
def check_params(params):
    """
        Raises TypeError if there are extra or missing keys in the dict.

        `params` is the dict that makes up the second element of the array
        defining the color space.

        """
    tester = lambda WhitePoint, **kwargs: None
    tester(**params)


@classmethod
def register_global_factory(cls, klass, factory):
    """
        Create an association between a class and a global factory.
        """
    cls._global_factories[klass] = factory


@staticmethod
def unicode_translate(text, chars='', replacement='') ->str:
    """Replacement for the string.maketrans function

        :type text: str
        :type chars: str
        :type replacement: str
        :return:
        """
    for char in chars:
        text = text.replace(char, replacement[chars.index(char)])
    return text


def file_put_contents(filename, string):
    """Write string to filename."""
    with open(filename, 'w') as f:
        f.write(string)


def check_data_2d(x, y, z):
    """
    Performs consistency checks on the data passed into make_film_2d.

    These checks are only done when both x, y, and z arguments are passed into
    the function.

    Parameters
    ----------
    x : array_like
        Array specifying the x axis.
    y : array_like
        Array specifying the y axis.
    z : array_like
        Three dimensional array assumed to be of the form z(t, x, y). This
        specifies the values to be plotted as a function of time.
    """
    x_s = x.shape
    y_s = y.shape
    z_s = z.shape
    if len(x_s) != 1:
        raise IndexError('x must be one dimensional.')
    if len(y_s) != 1:
        raise IndexError('y must be one dimensional.')
    if len(z_s) != 3:
        raise IndexError('y must be three dimensional.')
    if x_s[0] != z_s[1]:
        raise ValueError('x and z must have the same length: {0}, {1}'.
            format(x_s[0], z_s[1]))
    elif y_s[0] != z_s[2]:
        raise ValueError('y and z must have the same length: {0}, {1}'.
            format(y_s[0], z_s[2]))


@classmethod
def to_json_type(cls):
    """Return a JSON safe dictionary representing the snippet type"""
    return {'id': cls.id, 'label': cls.label, 'image_url': cls.get_image_url()}


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

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


@classmethod
def get_user_profiles(cls):
    """Yield a series of all user profiles on this site which satisfy this
        role.

        """
    from lino.modlib.users.choicelists import UserTypes
    for p in UserTypes.items():
        if p.has_required_roles([cls]):
            yield p


def _or(_, left, right):
    """Helper for match_spec."""
    return left or right


def delete_residues(fhandle, residue_range, step):
    """Deletes residues within a certain numbering range.
    """
    prev_res = None
    res_counter = -1
    records = 'ATOM', 'HETATM', 'TER', 'ANISOU'
    for line in fhandle:
        if line.startswith(records):
            res_id = line[21:26]
            if res_id != prev_res:
                prev_res = res_id
                res_counter += 1
            if int(line[22:26]) in residue_range and res_counter % step == 0:
                continue
        yield line


@classmethod
def observe(cls, observer):
    """
        Register an observer with the Model.

        :param observer: The observer
        """
    for event in cls.get_observable_events():
        if hasattr(observer, event):
            cls._register_model_event(event, getattr(observer, event))


def is_output_layer(layer, model):
    """Test if `layer` is an output layer."""
    return layer.name in model.output_names


@classmethod
def from_name(cls, name, lang='en', property=False):
    """A Wikidata entry with the given name."""
    id = cls.search_entity(name, property, lang)
    if id is None:
        raise KeyError('No entity found for {} ({})'.format(name, lang))
    return cls(id, lang)


def SizeExpsOther(t):
    """Other expenses per policy at time t"""
    return 0


def extract_mark_tx(tx, config):
    """
    Extract mark from transaction, if any.

    Args:
        tx: transaction instance.
        config: A configuration string in JSON format given in source file.
    Returns:
        string of mark or False.
    """
    for alias in config['aliases_after']:
        if hasattr(tx, 'meta') and tx.meta and alias in tx.meta:
            return tx.meta[alias]
        if hasattr(tx, 'tags') and tx.tags:
            for tag in tx.tags:
                if tag[0:len(alias + config['alias_seperator'])
                    ] == alias + config['alias_seperator'] or tag == alias:
                    return tag[len(alias + config['alias_seperator']):] or ''
    return False


def bandwidth(bandwidth):
    """
    Bandwidth is in gigabytes per day.
    -1 is "unlimited".
    0 means no bandwidth. Only valid if ipv4 and ipv6 are False.
    """
    if isinstance(bandwidth, int):
        if bandwidth >= -1:
            return True
        else:
            raise ValueError('bandwidth can be no lower than -1.')
    else:
        raise TypeError('bandwidth must be integer.')


def _check_range(val_range, min_val=None, max_val=None):
    """ Check whether the range is a valid range.

    Args
        val_range: A pair of lower and upper bound.
        min_val: Minimal value for the lower bound.
        max_val: Maximal value for the upper bound.
    """
    if val_range[0] > val_range[1]:
        raise ValueError('interval lower bound > upper bound')
    if min_val is not None and val_range[0] < min_val:
        raise ValueError('invalid interval lower bound')
    if max_val is not None and val_range[1] > max_val:
        raise ValueError('invalid interval upper bound')


def rmdup(obj):
    """Return a list without duplicates."""
    new = []
    for i in obj:
        if i not in new:
            new.append(i)
    return type(obj)(new)


def allow_usr_lib(path):
    """
    White-list helper that allows anything installed in /usr/lib/
    """
    return path.startswith('/usr/lib/')


def _buildMessageFormat(vin=None, rin=None, msg=None):
    """Builds a deprecation warning message from the arguments.

    :arg vin: Optional version - the warning message will mention that the
              function is deprecated from this version.

    :arg rin: Optional version - the warning message will mention that the
              function will be removed in this version.

    :arg msg: Optional message to use in the warning.

    :returns: A format string which needs to be formatted with a ``{name}``.
    """
    if vin is not None and rin is not None:
        msgfmt = (
            '{{name}} is deprecated from version {vin} and will be removed in {rin}.'
            .format(vin=vin, rin=rin))
    elif vin is not None:
        msgfmt = '{{name}} is deprecated from version {vin}.'.format(vin=vin)
    elif rin is not None:
        msgfmt = '{{name}} is deprecated and will be removed in {rin}.'.format(
            rin=rin)
    else:
        msgfmt = '{{name}} is deprecated.'
    if msg is not None:
        msgfmt = msgfmt + ' ' + msg
    return msgfmt


def get_maxwidth(format):
    """Infer preferred max figure width from output format."""
    if format == 'pdf':
        maxwidth = 668
    else:
        maxwidth = 1024
    return maxwidth


@classmethod
def get_context(cls):
    """Returns a user defined context. Override this in your ServiceBase
        subclass to customize context generation."""
    return None


@classmethod
def parse(cls, reader, block_length):
    """returns this metadata block from a BitstreamReader"""
    return cls(application_id=reader.read_bytes(4), data=reader.read_bytes(
        block_length - 4))


def mayberevnum(repo, prefix):
    """Checks if the given prefix may be mistaken for a revision number"""
    try:
        i = int(prefix)
        if prefix != b'0' and prefix[0:1] == b'0' or i >= len(repo):
            return False
        return True
    except ValueError:
        return False


def _check_notebook_extension(notebook_path):
    """
    Check the path extension of the notebook.

    Parameters
    ----------
    notebook_path : str
        Path of target notebook.

    Raises
    ------
    IOError
        If the extension is invalid.
    """
    extension_str = notebook_path.split('.')[-1]
    if extension_str.endswith('ipynb'):
        return
    err_msg = (
        'The extension is invalid. Please Specify a path of `.ipynb` extension.'
        )
    raise IOError(err_msg)


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 clear_db_env():
    """
    Unset global configuration variables for database.
    """
    global _FACADE
    _FACADE = None


def rename_dictionary_keys(data, mapping, default_value=None):
    """
    Renames the dictionary's keys based on the mapping. If any 'old value' isn't present it'll be added and assigned the value of 'default_value'.
    e.g. of mapping definition: {'crap name 1':'great name 1', 'crap name 2': 'great name 2'}
    Does NOT maintain key order!
    Key name is case sensitive.
    """
    reconstituted = {}
    for old_name, new_name in mapping.items():
        reconstituted[new_name] = data.get(old_name, default_value)
    return reconstituted


def cord(value):
    """Convert (str or int) to ord"""
    if isinstance(value, str):
        return ord(value)
    return value


def select_linked_pick(deselect: bool=False):
    """Select all control points linked to already selected ones

    :param deselect: Deselect, Deselect linked control points rather than selecting them
    :type deselect: bool
    """
    pass


def rectified_linear(x):
    """Bounds functions with a range of [-infinity, 1] to [0, 1].

    Negative values are clipped to 0.

    This function is used for scorers, e.g. R^2 (regression metric), where
    1 is the best possible score, 0 indicates expected value of y, and negative
    numbers are worse than predicting the mean.
    """
    return 0 if x < 0 else x


def hash_to_value(x):
    """Convert a little-endian binary hash to an integer value (to e.g. compare to a proof of
    work target).
    """
    return int.from_bytes(x, 'little')


def p_type_paren(p):
    """type : LPAREN type RPAREN"""
    p[0] = p[2]


def vectorize(vectorizer, sentences):
    """Vectorizes sentences
    :argument vectorize: CountVectorize
    :argument sentences: list of str (list of sentence)
    :returns a sparse matrix to feed LDA with (for each document, number of each word) (LDA doesn't take order into account)
    """
    return vectorizer.fit_transform(sentences)


def contextfilter(f):
    """Decorator for marking context dependent filters. The current
    :class:`Context` will be passed as first argument.
    """
    f.contextfilter = True
    return f


def get_last_bit(label):
    """
        Gets the last bit from a bytestring.

        :param bytes label: any bytes object
        :return: the last bit
        :rtype: bool

        .. code-block:: python

            >>> import os
            >>> from gabes.utils import get_last_bit
            >>> b1 = os.urandom(10)
            >>> b1
            b'\\xf3\\x9e\\xb0w,|\\xd9\\xa8\\xd73'
            >>> get_last_bit(b1)
            False

    """
    last_byte = label[-1]
    return bool(last_byte >> 7 & 1)


def __get_data_at_step(file, mtm_dat, var):
    """

    Find the data step that corresponds to an BPM image file and get the
    corresponding data (key `var`) from an MTM data file.

    Parameters
    ----------
    file: str
        The path to a BMP image file. The file name given by the PCS instrument
        may not be changed, otherwise the step extraction may fail.
    mtm_dat: dict
        Instrument output data loaded from npz database file.
    var: str
        A key in the npz database.

    Returns
    -------
    dat: ndarray
        An array containing a single data point (float, int)

    """
    if '_ZERO.bmp' in file:
        step = 1
    else:
        step = int(file.split('_')[-1].replace('.bmp', ''))
    step_idx = mtm_dat['step_start'][step - 1]
    dat = mtm_dat[var][step_idx]
    return dat


def add_parser_arguments(parser):
    """ Add additional subcommands onto this command """
    parser.add_argument('network', metavar='NETWORK', type=str, nargs=1,
        help='Ethereum network to connect the console to')
    parser.add_argument('-a', '--address', type=str, dest='address', help=
        'Address of the Ethereum account to use for deployment')
    parser.add_argument('-p', '--passphrase', metavar='PASSPHRASE', type=
        str, nargs='?', dest='passphrase', help=
        'The passphrase to use to encrypt the keyfile. Leave empty for prompt.'
        )
    return parser


def setBroadcastAllowed(enabled):
    """
        Set whether this port may broadcast.

        @param enabled: Whether the port may broadcast.
        @type enabled: L{bool}
        """


def as_dict(value, key):
    """ Jinja2 filter which constructs a dictionary from a key/value pair.
	"""
    return {key: value}


def sources_list(sources, params):
    """
    Adds defined list of sources to params

    Parameters
    ----------
    sources : list
        Payment sources
    params : dict
        Default params

    Returns
    -------
    dict
        params with sources
    """
    if isinstance(sources, list):
        for source in sources:
            params['sources[{0}]'.format(sources.index(source))] = source
    else:
        raise TypeError('You should use list Type for sources')
    return params


def add_password(auth_handler, uri, username, passwd, realm=None):
    """
    See: https://gist.github.com/dnozay/194d816aa6517dc67ca1
    add credentials for basic auth to the password manager
    """
    auth_handler.add_password(realm=realm, uri=uri, user=username, passwd=
        passwd)


def get_fileobject_size(file_object):
    """Return byte size of file-object

    Parameters
    ----------
    file_object : file object

    Returns
    -------
    nbytes : int
    """
    file_object.seek(0, 2)
    nbytes = file_object.tell()
    file_object.seek(0)
    return nbytes


def gen_vtk(savedir, points, indices, norms, colormap=True, DATA=None):
    """
    points - x, y, z
    indices - vertices of the triangle mesh
    DATA - dic, key is 'cosine' or 'atm' or others
    num - number of cell data
    """
    num_points = len(points.T)
    num_tri = len(indices)
    f = open(savedir, 'w')
    f.write('# vtk DataFile Version 2.0\n')
    f.write('test\n')
    f.write('ASCII\n')
    f.write('DATASET POLYDATA\n')
    f.write('POINTS %s double\n' % num_points)
    for i in range(num_points):
        x = points[0, i]
        y = points[1, i]
        z = points[2, i]
        f.write('%.8f %.8f %.8f\n' % (x, y, z))
    f.write('POLYGONS %s %s\n' % (num_tri, num_tri * 4))
    for i in range(num_tri):
        id1 = indices[i, 0]
        id2 = indices[i, 1]
        id3 = indices[i, 2]
        f.write('3 %.0f %.0f %.0f\n' % (id1, id2, id3))
    f.write('CELL_DATA %s\n' % num_tri)
    f.write('NORMALS cell_normals float\n')
    for i in range(num_tri):
        nx = norms[i, 0]
        ny = norms[i, 1]
        nz = norms[i, 2]
        f.write('%.8f %.8f %.8f\n' % (nx, ny, nz))
    if colormap:
        totalnum = len(DATA)
        f.write('FIELD PrimaryData %s\n' % totalnum)
        interest = DATA.keys()
        for m in interest:
            f.write('%s 1 %s double\n' % (m, num_tri))
            for i in range(num_tri):
                f.write('%.8f\n' % DATA[m][i])
        f.close()


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

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


def interval_lengths(bits):
    """
    Get the length distribution of all contiguous runs of set bits from
    """
    end = 0
    while True:
        start = bits.next_set(end)
        if start == bits.size:
            break
        end = bits.next_clear(start)
        yield end - start


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

        :param SfTeamJoinDetails val:
        :rtype: EventDetails
        """
    return cls('sf_team_join_details', val)


def afterDaemonize():
    """
        Hook to be called immediately after daemonization. This may only be
        called after L{beforeDaemonize} had been called previously.

        @return: C{None}.
        """


def list_groups(client, display_name=None, query_filter=None):
    """
    list groups in the directory
    """
    sub_filters = []
    if query_filter:
        sub_filters.append(query_filter)
    if display_name:
        sub_filters.append("startswith(displayName,'{}')".format(display_name))
    return client.list(filter=' and '.join(sub_filters))


def read_file(fo):
    """Get rows from file-like"""
    import fastavro
    with fo as f:
        return list(fastavro.iter_avro(f))


def removescale(img, a=[1200, 1230, 0, 500], p=255):
    """
        Remove the scale bar from image
    """
    img[a[0]:a[1], a[2]:a[3]] = p
    return img


def ij2bl(i, j):
    """
    Convert antenna numbers to baseline number

    Parameters
    ----------
    i : int
        first antenna number
    j : int
        second antenna number

    Returns
    -------
    int
        baseline number
    """
    if i > j:
        i, j = j, i
    if j + 1 < 256:
        return 256 * (i + 1) + (j + 1)
    return 2048 * (i + 1) + (j + 1) + 65536


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

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


def p_language_blocks(t):
    """language_blocks : language_block
                       | language_blocks language_block"""
    if len(t) == 2:
        t[0] = [t[1]]
    else:
        t[0] = t[1] + [t[2]]


def _add_duration_information(data, ev, duration):
    """Determine event duration in one of a few ways."""
    if duration is None:
        duration = 0
    elif duration in data:
        duration = data[duration]
    ev['duration'] = duration
    return ev


@classmethod
def get_providers(cls, request=None):
    """
        Return a list of all registered data providers' codes and titles
        :param request: The current HttpRequest
        :return: list
        """
    return cls.get(request, f'/sources/api/provider')


def bake():
    """Bake fluid simulation

    """
    pass


def pad_pkcs5(data, block_size):
    """
    Returns the data padded using PKCS5.
    For a block size B and data with N bytes in the last block, PKCS5
    pads the data with B-N bytes of the value B-N.

    :param data: Data to be padded.
    :type data: :class:`str`

    :param block_size: Size of the block.
    :type block_size: :class:`int`

    :return: :class:`str` -- PKCS5 padded string.
    """
    pad = block_size - len(data) % block_size
    return data + pad * chr(pad)


def makeUnique(strings):
    """ make a list of strings unique by appending arbitrary numbers,
        e.g. if string "abc" appears twice in the list, the occurrences are
        replaced with "abc_001" and "abc_002"
    """
    result = list(strings)
    nStrings = len(strings)
    sDict = {}
    for i in range(nStrings):
        name = strings[i]
        if name in sDict:
            sDict[name].append(i)
        else:
            sDict[name] = [i]
    if len(sDict) != nStrings:
        for name in sDict:
            indexList = sDict[name]
            if len(indexList) > 1:
                for i in range(len(indexList)):
                    result[indexList[i]] += '_%03u' % (i + 1)
    return result


def int_set_null(int_value):
    """sql util function"""
    return 'null' if int_value is None else str(int_value)


@classmethod
def get_all(cls):
    """Get all channels """
    return [cls.ALL, cls.CHINA, cls.MUNDO, cls.IBERO_AMERICA, cls.ECONOMIA,
        cls.CULTURA, cls.DEPORTES, cls.OTHER]


def clean(threshold: float=0.001, channels: bool=False):
    """Simplify F-Curves by removing closely spaced keyframes

    :param threshold: Threshold
    :type threshold: float
    :param channels: Channels
    :type channels: bool
    """
    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 load(cls, metadata):
    """load class data from dict.
        """
    return cls(classname=metadata.get('classname'), attrs=metadata.get(
        'attrs'), keys=metadata.get('keys'), data=metadata.get('data'),
        collection=metadata.get('collection'))


def syncplugins(plugmgr, existing, createfn, deletefn):
    """
    Helper function for syncing plugins. Backend agnostic - all backend
    functionality is passed through ``deletefn`` and ``createfn``

    plugmgr     - Plugin manager used
    existing    - A list of existing plugins. Each item needs to have ``type``,
                  ``name``, and ``run`` attributes.
    deletefn    - Deletion function. This will be called when the plugin should
                  be deleted. It takes one argument - the deleted plugin. This
                  will be an item from the ``existing`` list.
    createfn    - Function used to create new plugin. It should take one
                  argument - ``PluginDesc`` with description of the new plugin.
    """
    plugmgr.discover()
    newsnipers = list(plugmgr.iter())
    for plugin in existing:
        if plugmgr.find(plugin.type, plugin.name):
            plug_eq = lambda x: x.type != plugin.type or x.name != plugin.name
            newsnipers = filter(plug_eq, newsnipers)
        else:
            deletefn(plugin)
    for sniper in newsnipers:
        createfn(sniper)


def permission_denied(spawn):
    """
    handles connection refused scenarios
    """
    raise ConnectionError('Permission denied for device "%s"' % str(spawn))


def escape(data, quote=True):
    """
  Escapes special characters into their html entities
  Replace special characters "&", "<" and ">" to HTML-safe sequences.
  If the optional flag quote is true, the quotation mark character (")
  is also translated.

  This is used to escape content that appears in the body of an HTML document
  """
    data = data.replace('&', '&')
    data = data.replace('<', '<')
    data = data.replace('>', '>')
    if quote:
        data = data.replace('"', '"')
    return data


@staticmethod
def collect_data(context):
    """
        Collect data for converter.

        """
    context.parser.parse(context)
    context.files.find_cmake_project_languages(context)


def get_first_val(key_tuple, dict_obj):
    """Return the first value mapped by a key in the given tuple.

    Parameters
    ----------
    key_tuple : tuple
        The keys to use for extraction, in order.
    dict_obj : dict
        The dict to extract from.

    Returns
    -------
    value : object
        The extracted value, if exists. Otherwise, raises KeyError.

    Example
    -------
    >>> dict_obj = {'a': 1, 'c': 2}
    >>> get_first_val(('a', 'b', 'c'), dict_obj)
    1
    >>> get_first_val(('b', 'c', 'a'), dict_obj)
    2
    >>> get_first_val(('e'), dict_obj)
    Traceback (most recent call last):
     ...
    KeyError: 'None of the provided keys was found'
    """
    for key in key_tuple:
        try:
            return dict_obj[key]
        except KeyError:
            pass
    raise KeyError('None of the provided keys was found')


def cstr(v):
    """ Convert Python 3.x string to C compatible char *. """
    return v.encode('utf8')


def gen_cookie(username, hash_password):
    """
    Build secure cookie content as a string containing:
        - content length (excluding length itself)
        - role_name
        - 16 first chars of the hash password

    Part of hash password is there for 2 main reasons:

        1/ If the cookie secret key is stolen, the attacker will be able to
        build a valid secure cookie, so in this situation having a
        non-predictibable variable - part of hash password -  wich can be
        checked on server side will render the attack effective less, unless
        if the attacker knows role's password.

        2/ We don't want to see the full hash password stored in a cookie.
    """
    content = '%s:%s' % (username, hash_password[:15])
    return '%s:%s' % (len(content) + 1, content)