def load_general_header(fhandle):
    """ Load the general header block (block 1 for each time)

    Parameters
    ------------
    fhandle : (file handle)
        File handle

    Returns
    ----------
    data : list
        List of data values containing: P field,
        Number of days from 01/01/1950, number of miliseconds in the day,
        UT as datetime, Orbit number, downward (False) upward (True) indicator
    meta : dict
        Dictionary with meta data for keys: 'telemetry station',
        'software processing version', 'software processing subversion',
        'calibration file version', and 'calibration file subversion',
        'data names', 'data units'

    """
    import codecs
    import datetime as dt
    block_size = 38
    chunk = fhandle.read(block_size)
    if len(chunk) != block_size:
        return list(), dict()
    year = int(codecs.encode(chunk[8:10], 'hex'), 16)
    month = int(codecs.encode(chunk[10:12], 'hex'), 16)
    day = int(codecs.encode(chunk[12:14], 'hex'), 16)
    hour = int(codecs.encode(chunk[14:16], 'hex'), 16)
    minute = int(codecs.encode(chunk[16:18], 'hex'), 16)
    sec = int(codecs.encode(chunk[18:20], 'hex'), 16)
    microsec = int(codecs.encode(chunk[20:22], 'hex'), 16) * 1000
    dtime = dt.datetime(year, month, day, hour, minute, sec, microsec)
    data = [int(codecs.encode(chunk[:1], 'hex'), 16), int(codecs.encode(
        chunk[1:4], 'hex'), 16), int(codecs.encode(chunk[4:8], 'hex'), 16),
        dtime, int(codecs.encode(chunk[22:24], 'hex'), 16), bool(int(codecs
        .encode(chunk[24:26], 'hex'), 16))]
    meta = {'telemetry station': chunk[26:34],
        'software processing version': int(codecs.encode(chunk[34:35],
        'hex'), 16), 'software processing subversion': int(codecs.encode(
        chunk[35:36], 'hex'), 16), 'calibration file version': int(codecs.
        encode(chunk[36:37], 'hex'), 16), 'calibration file subversion':
        int(codecs.encode(chunk[37:38], 'hex'), 16), 'data names': [
        'P_field', 'epoch_time', 'time_of_day', 'UT', 'orbit_number',
        'orbit_type'], 'data units': {'P_field': 'N/A', 'epoch_time':
        'days since 1/1/1950', 'time_of_day': 'ms', 'UT': 'datetime',
        'orbit_number': 'N/A', 'orbit_type': 'N/A'}}
    return data, meta


def make_ccys(db):
    """
    Create the currency dictionary
    """
    dfr = 4
    dollar = '\\u0024'
    peso = '\\u20b1'
    kr = 'kr'
    insert = db.insert
    insert('EUR', '978', 'EU', 1, 'Euro', dfr, 'EU', '30/360', 'ACT/360',
        future='FE', symbol='\\u20ac', html='€')
    insert('GBP', '826', 'BP', 2, 'British Pound', dfr, 'GB', 'ACT/365',
        'ACT/365', symbol='\\u00a3', html='£')
    insert('AUD', '036', 'AD', 3, 'Australian Dollar', dfr, 'AU', 'ACT/365',
        'ACT/365', symbol=dollar, html='$')
    insert('NZD', '554', 'ND', 4, 'New-Zealand Dollar', dfr, 'NZ',
        'ACT/365', 'ACT/365', symbol=dollar, html='$')
    insert('USD', '840', 'UD', 5, 'US Dollar', 0, 'US', '30/360', 'ACT/360',
        future='ED', symbol=dollar, html='$')
    insert('CAD', '124', 'CD', 6, 'Canadian Dollar', dfr, 'CA', 'ACT/365',
        'ACT/365', symbol=dollar, html='$')
    insert('CHF', '756', 'SF', 7, 'Swiss Franc', dfr, 'CH', '30/360',
        'ACT/360', symbol='Fr', html='₣')
    insert('NOK', '578', 'NK', 8, 'Norwegian Krona', dfr, 'NO', '30/360',
        'ACT/360', symbol=kr, html=kr)
    insert('SEK', '752', 'SK', 9, 'Swedish Krona', dfr, 'SE', '30/360',
        'ACT/360', symbol=kr, html=kr)
    insert('DKK', '208', 'DK', 10, 'Danish Krona', dfr, 'DK', '30/360',
        'ACT/360', symbol=kr, html=kr)
    insert('JPY', '392', 'JY', 10000, 'Japanese Yen', 2, 'JP', 'ACT/365',
        'ACT/360', symbol='\\u00a5', html='¥')
    insert('CNY', '156', 'CY', 680, 'Chinese Renminbi', dfr, 'CN',
        'ACT/365', 'ACT/365', symbol='\\u00a5', html='¥')
    insert('KRW', '410', 'KW', 110000, 'South Korean won', 2, 'KR',
        'ACT/365', 'ACT/365', symbol='\\u20a9', html='₩')
    insert('SGD', '702', 'SD', 15, 'Singapore Dollar', dfr, 'SG', 'ACT/365',
        'ACT/365', symbol=dollar, html='$')
    insert('IDR', '360', 'IH', 970000, 'Indonesian Rupiah', 0, 'ID',
        'ACT/360', 'ACT/360', symbol='Rp', html='Rp')
    insert('THB', '764', 'TB', 3300, 'Thai Baht', 2, 'TH', 'ACT/365',
        'ACT/365', symbol='\\u0e3f', html='฿')
    insert('TWD', '901', 'TD', 18, 'Taiwan Dollar', dfr, 'TW', 'ACT/365',
        'ACT/365', symbol=dollar, html='$')
    insert('HKD', '344', 'HD', 19, 'Hong Kong Dollar', dfr, 'HK', 'ACT/365',
        'ACT/365', symbol='\\u5713', html='HK$')
    insert('PHP', '608', 'PP', 4770, 'Philippines Peso', dfr, 'PH',
        'ACT/360', 'ACT/360', symbol=peso, html='₱')
    insert('INR', '356', 'IR', 4500, 'Indian Rupee', dfr, 'IN', 'ACT/365',
        'ACT/365', symbol='\\u20a8', html='₨')
    insert('MYR', '458', 'MR', 345, 'Malaysian Ringgit', dfr, 'MY',
        'ACT/365', 'ACT/365')
    insert('VND', '704', 'VD', 1700000, 'Vietnamese Dong', 0, 'VN',
        'ACT/365', 'ACT/365', symbol='\\u20ab', html='₫')
    insert('BRL', '986', 'BC', 200, 'Brazilian Real', dfr, 'BR', 'BUS/252',
        'BUS/252', symbol='R$')
    insert('PEN', '604', 'PS', 220, 'Peruvian New Sol', dfr, 'PE',
        'ACT/360', 'ACT/360', symbol='S/.')
    insert('ARS', '032', 'AP', 301, 'Argentine Peso', dfr, 'AR', '30/360',
        'ACT/360', symbol=dollar, html='$')
    insert('MXN', '484', 'MP', 1330, 'Mexican Peso', dfr, 'MX', 'ACT/360',
        'ACT/360', symbol=dollar, html='$')
    insert('CLP', '152', 'CH', 54500, 'Chilean Peso', 2, 'CL', 'ACT/360',
        'ACT/360', symbol=dollar, html='$')
    insert('COP', '170', 'CL', 190000, 'Colombian Peso', 2, 'CO', 'ACT/360',
        'ACT/360', symbol=dollar, html='$')
    insert('JMD', '388', 'JD', 410, 'Jamaican Dollar', dfr, 'JM', 'ACT/360',
        'ACT/360', symbol=dollar, html='$')
    insert('TTD', '780', 'TT', 410, 'Trinidad and Tobago Dollar', dfr, 'TT',
        'ACT/360', 'ACT/360', symbol=dollar, html='$')
    insert('BMD', '060', 'BD', 410, 'Bermudian Dollar', dfr, 'BM', symbol=
        dollar, html='$')
    insert('CZK', '203', 'CK', 28, 'Czech Koruna', dfr, 'CZ', 'ACT/360',
        'ACT/360', symbol='\\u004b\\u010d')
    insert('PLN', '985', 'PZ', 29, 'Polish Zloty', dfr, 'PL', 'ACT/ACT',
        'ACT/365', symbol='\\u0050\\u0142')
    insert('TRY', '949', 'TY', 30, 'Turkish Lira', dfr, 'TR', 'ACT/360',
        'ACT/360', symbol='\\u0054\\u004c')
    insert('HUF', '348', 'HF', 32, 'Hungarian Forint', dfr, 'HU', 'ACT/365',
        'ACT/360', symbol='Ft', html='Ft')
    insert('RON', '946', 'RN', 34, 'Romanian Leu', dfr, 'RO', 'ACT/360',
        'ACT/360')
    insert('RUB', '643', 'RR', 36, 'Russian Ruble', dfr, 'RU', 'ACT/ACT',
        'ACT/ACT', symbol='\\u0440\\u0443\\u0431')
    insert('HRK', '191', 'HK', 410, 'Croatian kuna', dfr, 'HR', symbol='kn')
    insert('KZT', '398', 'KT', 410, 'Tenge', dfr, 'KZ', symbol='\\u20b8',
        html='₸')
    insert('BGN', '975', 'BN', 410, 'Bulgarian Lev', dfr, 'BG', symbol=
        '\\u043b\\u0432.', html='лв')
    insert('ILS', '376', 'IS', 410, 'Israeli Shekel', dfr, 'IL', 'ACT/365',
        'ACT/365', symbol='\\u20aa', html='₪')
    insert('AED', '784', 'AE', 410, 'United Arab Emirates Dirham', dfr, 'AE')
    insert('QAR', '634', 'QA', 410, 'Qatari Riyal', dfr, 'QA', symbol=
        '\\ufdfc', html='﷼')
    insert('SAR', '682', 'SR', 410, 'Saudi Riyal', dfr, 'SA', symbol=
        '\\ufdfc', html='﷼')
    insert('EGP', '818', 'EP', 550, 'Egyptian Pound', dfr, 'EG', symbol=
        '\\u00a3', html='£')
    insert('NGN', '566', 'NG', 650, 'Nigerian Naira', dfr, 'NG', symbol=
        '\\u20a6', html='₦')
    insert('ZAR', '710', 'SA', 750, 'South African Rand', dfr, 'ZA',
        'ACT/365', 'ACT/365', symbol='R', html='R')
    insert('XBT', '000', 'BT', -1, 'Bitcoin', 8, 'WW', symbol='\\u0e3f',
        html='฿')


def hide_fields_in_newer_versions(obj):
    """This method hides fields that were added in newer API versions.

    Certain node fields were introduced at certain API versions.
    These fields are only made available when the request's API version
    matches or exceeds the versions when these fields were introduced.
    """
    pass


def HDUCards(headers, hdu=0):
    """
    Generates HDU cards for inclusion in the de-trended light curve FITS file.
    Used internally.

    """
    if headers is None:
        return []
    if hdu == 0:
        tpf_header = headers[0]
        entries = ['TELESCOP', 'INSTRUME', 'OBJECT', 'KEPLERID', 'CHANNEL',
            'MODULE', 'OUTPUT', 'CAMPAIGN', 'DATA_REL', 'OBSMODE',
            'TTABLEID', 'RADESYS', 'RA_OBJ', 'DEC_OBJ', 'EQUINOX', 'KEPMAG']
    elif hdu == 1 or hdu == 6:
        tpf_header = headers[1]
        entries = ['WCSN4P', 'WCAX4P', '1CTY4P', '2CTY4P', '1CUN4P',
            '2CUN4P', '1CRV4P', '2CRV4P', '1CDL4P', '2CDL4P', '1CRP4P',
            '2CRP4P', 'WCAX4', '1CTYP4', '2CTYP4', '1CRPX4', '2CRPX4',
            '1CRVL4', '2CRVL4', '1CUNI4', '2CUNI4', '1CDLT4', '2CDLT4',
            '11PC4', '12PC4', '21PC4', '22PC4', 'WCSN5P', 'WCAX5P',
            '1CTY5P', '2CTY5P', '1CUN5P', '2CUN5P', '1CRV5P', '2CRV5P',
            '1CDL5P', '2CDL5P', '1CRP5P', '2CRP5P', 'WCAX5', '1CTYP5',
            '2CTYP5', '1CRPX5', '2CRPX5', '1CRVL5', '2CRVL5', '1CUNI5',
            '2CUNI5', '1CDLT5', '2CDLT5', '11PC5', '12PC5', '21PC5',
            '22PC5', 'WCSN6P', 'WCAX6P', '1CTY6P', '2CTY6P', '1CUN6P',
            '2CUN6P', '1CRV6P', '2CRV6P', '1CDL6P', '2CDL6P', '1CRP6P',
            '2CRP6P', 'WCAX6', '1CTYP6', '2CTYP6', '1CRPX6', '2CRPX6',
            '1CRVL6', '2CRVL6', '1CUNI6', '2CUNI6', '1CDLT6', '2CDLT6',
            '11PC6', '12PC6', '21PC6', '22PC6', 'WCSN7P', 'WCAX7P',
            '1CTY7P', '2CTY7P', '1CUN7P', '2CUN7P', '1CRV7P', '2CRV7P',
            '1CDL7P', '2CDL7P', '1CRP7P', '2CRP7P', 'WCAX7', '1CTYP7',
            '2CTYP7', '1CRPX7', '2CRPX7', '1CRVL7', '2CRVL7', '1CUNI7',
            '2CUNI7', '1CDLT7', '2CDLT7', '11PC7', '12PC7', '21PC7',
            '22PC7', 'WCSN8P', 'WCAX8P', '1CTY8P', '2CTY8P', '1CUN8P',
            '2CUN8P', '1CRV8P', '2CRV8P', '1CDL8P', '2CDL8P', '1CRP8P',
            '2CRP8P', 'WCAX8', '1CTYP8', '2CTYP8', '1CRPX8', '2CRPX8',
            '1CRVL8', '2CRVL8', '1CUNI8', '2CUNI8', '1CDLT8', '2CDLT8',
            '11PC8', '12PC8', '21PC8', '22PC8', 'WCSN9P', 'WCAX9P',
            '1CTY9P', '2CTY9P', '1CUN9P', '2CUN9P', '1CRV9P', '2CRV9P',
            '1CDL9P', '2CDL9P', '1CRP9P', '2CRP9P', 'WCAX9', '1CTYP9',
            '2CTYP9', '1CRPX9', '2CRPX9', '1CRVL9', '2CRVL9', '1CUNI9',
            '2CUNI9', '1CDLT9', '2CDLT9', '11PC9', '12PC9', '21PC9',
            '22PC9', 'INHERIT', 'EXTNAME', 'EXTVER', 'TELESCOP', 'INSTRUME',
            'OBJECT', 'KEPLERID', 'RADESYS', 'RA_OBJ', 'DEC_OBJ', 'EQUINOX',
            'EXPOSURE', 'TIMEREF', 'TASSIGN', 'TIMESYS', 'BJDREFI',
            'BJDREFF', 'TIMEUNIT', 'TELAPSE', 'LIVETIME', 'TSTART', 'TSTOP',
            'LC_START', 'LC_END', 'DEADC', 'TIMEPIXR', 'TIERRELA',
            'INT_TIME', 'READTIME', 'FRAMETIM', 'NUM_FRM', 'TIMEDEL',
            'DATE-OBS', 'DATE-END', 'BACKAPP', 'DEADAPP', 'VIGNAPP', 'GAIN',
            'READNOIS', 'NREADOUT', 'TIMSLICE', 'MEANBLCK', 'LCFXDOFF',
            'SCFXDOFF']
    elif hdu == 3 or hdu == 4 or hdu == 5:
        tpf_header = headers[2]
        entries = ['TELESCOP', 'INSTRUME', 'OBJECT', 'KEPLERID', 'RADESYS',
            'RA_OBJ', 'DEC_OBJ', 'EQUINOX', 'WCSAXES', 'CTYPE1', 'CTYPE2',
            'CRPIX1', 'CRPIX2', 'CRVAL1', 'CRVAL2', 'CUNIT1', 'CUNIT2',
            'CDELT1', 'CDELT2', 'PC1_1', 'PC1_2', 'PC2_1', 'PC2_2',
            'WCSNAMEP', 'WCSAXESP', 'CTYPE1P', 'CUNIT1P', 'CRPIX1P',
            'CRVAL1P', 'CDELT1P', 'CTYPE2P', 'CUNIT2P', 'CRPIX2P',
            'CRVAL2P', 'CDELT2P', 'NPIXSAP', 'NPIXMISS']
    else:
        return []
    cards = []
    cards.append(('COMMENT', '************************'))
    cards.append(('COMMENT', '*     MISSION INFO     *'))
    cards.append(('COMMENT', '************************'))
    for entry in entries:
        try:
            cards.append(tuple(tpf_header[entry]))
        except KeyError:
            pass
    return cards


@classmethod
def _get_related_model_for_field(cls, field):
    """
        Get related model to which field has relationship to
        from property instance (e.g. ``ColumnProperty`` class or related)
        """
    return field._dependency_processor.mapper.class_


def rstrip(text, chars):
    """
    Right-strip chars from text.
    Return corresponding left and right substrings.
    """
    strip = text.rstrip(chars)
    return strip, text[len(strip):]


@classmethod
def str_dates_in_range(cls, after, before, str_dates):
    """Yield `(date, str)` for all elements of `str_dates` in `(before, after)`."""
    for sd in str_dates:
        try:
            d = cls.from_string(sd)
        except ValueError:
            pass
        else:
            if after and d <= after:
                continue
            if before and d >= before:
                continue
            yield d, sd


@staticmethod
def construct_subnet_id(subscription_id, resource_group_name,
    virtual_network_name, subnet_name):
    """construct subnet id"""
    return (
        '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Network/virtualNetworks/{}/subnets/{}'
        .format(subscription_id, resource_group_name, virtual_network_name,
        subnet_name))


def cMultiplyScalar():
    """
    Return the kernel source for cMultiplyScalar.
    """
    code_text = """
        KERNEL void cMultiplyScalar(
                     const float2 CA,
                GLOBAL_MEM float2 *CX)
        {
        // Scale CX by CA: CX=CA*CX
        //  CA: scaling factor(float2)
        //*CX: input, output array(float2)
        int gid = get_global_id(0);
        CX[gid].x=CA.x*CX[gid].x-CA.y*CX[gid].y;
        CX[gid].y=CA.x*CX[gid].y+CA.y*CX[gid].x;
        };
        """
    return code_text


def noise(factor: float=0.1):
    """Use vertex coordinate as texture coordinate

    :param factor: Factor
    :type factor: float
    """
    pass


def get_filepath(resource_id):
    """
    Returns the path to the location of the file associated with
    the resource with the given resource ID.
    """
    return '/var/lib/ckan/default/resources/' + resource_id[0:3
        ] + '/' + resource_id[3:6] + '/' + resource_id[6:]


def asoctal(s):
    """Convert the given octal string to an actual number."""
    return int(s, 8)


@staticmethod
def _init_qualifier_decl(qualifier_decl, qual_repo):
    """
        Initialize the flavors of a qualifier declaration if they are not
        already set.
        """
    assert qualifier_decl.name not in qual_repo
    if qualifier_decl.tosubclass is None:
        qualifier_decl.tosubclass = True
    if qualifier_decl.overridable is None:
        qualifier_decl.overridable = True
    if qualifier_decl.translatable is None:
        qualifier_decl.translatable = False


@classmethod
def modulus(cls):
    """
        Return the quotient ring's modulus; this is an element of the
        source ring(), not a residue class (QuotientRing element).
        """
    return cls._modulus


def _check_maybe(tensor):
    """ Checks that the tensor has a known rank. """
    if tensor.shape.ndims is None:
        raise ValueError(
            'Expected tensor (%s) to have known rank, but ndims == None.' %
            tensor)


def numba_typeref_ctor(*args, **kwargs):
    """A stub for use internally by Numba when a call is emitted
    on a TypeRef.
    """
    raise NotImplementedError('This function should not be executed.')


def parameters_ui(layout, params):
    """ Create the ui for the rig parameters.
    """
    r = layout.row()
    r.prop(params, 'separate_extra_layers')
    r = layout.row()
    r.active = params.separate_extra_layers
    col = r.column(align=True)
    row = col.row(align=True)
    row.prop(params, 'extra_layers', index=0, toggle=True, text='')
    row.prop(params, 'extra_layers', index=1, toggle=True, text='')
    row.prop(params, 'extra_layers', index=2, toggle=True, text='')
    row.prop(params, 'extra_layers', index=3, toggle=True, text='')
    row.prop(params, 'extra_layers', index=4, toggle=True, text='')
    row.prop(params, 'extra_layers', index=5, toggle=True, text='')
    row.prop(params, 'extra_layers', index=6, toggle=True, text='')
    row.prop(params, 'extra_layers', index=7, toggle=True, text='')
    row = col.row(align=True)
    row.prop(params, 'extra_layers', index=16, toggle=True, text='')
    row.prop(params, 'extra_layers', index=17, toggle=True, text='')
    row.prop(params, 'extra_layers', index=18, toggle=True, text='')
    row.prop(params, 'extra_layers', index=19, toggle=True, text='')
    row.prop(params, 'extra_layers', index=20, toggle=True, text='')
    row.prop(params, 'extra_layers', index=21, toggle=True, text='')
    row.prop(params, 'extra_layers', index=22, toggle=True, text='')
    row.prop(params, 'extra_layers', index=23, toggle=True, text='')
    col = r.column(align=True)
    row = col.row(align=True)
    row.prop(params, 'extra_layers', index=8, toggle=True, text='')
    row.prop(params, 'extra_layers', index=9, toggle=True, text='')
    row.prop(params, 'extra_layers', index=10, toggle=True, text='')
    row.prop(params, 'extra_layers', index=11, toggle=True, text='')
    row.prop(params, 'extra_layers', index=12, toggle=True, text='')
    row.prop(params, 'extra_layers', index=13, toggle=True, text='')
    row.prop(params, 'extra_layers', index=14, toggle=True, text='')
    row.prop(params, 'extra_layers', index=15, toggle=True, text='')
    row = col.row(align=True)
    row.prop(params, 'extra_layers', index=24, toggle=True, text='')
    row.prop(params, 'extra_layers', index=25, toggle=True, text='')
    row.prop(params, 'extra_layers', index=26, toggle=True, text='')
    row.prop(params, 'extra_layers', index=27, toggle=True, text='')
    row.prop(params, 'extra_layers', index=28, toggle=True, text='')
    row.prop(params, 'extra_layers', index=29, toggle=True, text='')
    row.prop(params, 'extra_layers', index=30, toggle=True, text='')
    row.prop(params, 'extra_layers', index=31, toggle=True, text='')
    r = layout.row()
    r.label(text='Bend rotation axis:')
    r.prop(params, 'primary_rotation_axis', text='')
    col = layout.column()
    col.prop(params, 'use_digit_twist')


def view_zoom_ratio(ratio: float=0.0):
    """Set the zoom ratio (based on clip size)

    :param ratio: Ratio, Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out
    :type ratio: float
    """
    pass


def tslash(apath):
    """Add a trailing slash to a path if it needs one.

    Doesn't use os.sep because you end up jiggered on windoze - when you
    want separators for URLs.
    """
    if apath and apath != '.' and not apath.endswith('/'
        ) and not apath.endswith('\\'):
        return apath + '/'
    else:
        return apath


def check_presence_of_mandatory_args(args, mandatory_args):
    """
    Checks whether all mandatory arguments are passed.

    This function aims at methods with many arguments
        which are passed as kwargs so that the order
        in which the are passed does not matter.

    :args: The dictionary passed as args.
    :mandatory_args: A list of keys that have to be
        present in the dictionary.
    :raise: :exc:`~ValueError`
    :returns: True, if all mandatory args are passed. If not,
        an exception is raised.

    """
    missing_args = []
    for name in mandatory_args:
        if name not in args.keys():
            missing_args.append(name)
    if len(missing_args) > 0:
        raise ValueError('Missing mandatory arguments: ' + ', '.join(
            missing_args))
    else:
        return True


def navmesh_reset():
    """Assign a new index to every face

    """
    pass


def _quote_float(s):
    """Returns s quoted if s can be coverted to a float."""
    try:
        float(s)
    except ValueError:
        return s
    else:
        return "'%s'" % s


def p_dimensions(p):
    """
    dimensions : dimensions ',' dimension
    subscripts : subscripts ',' expr
    """
    p[0] = p[1] + (p[3],)


@classmethod
def pluggable(cls, bot, token: str='', *args, **kwargs):
    """
        Pluggable version of Client. Inserts Client directly into your Bot client.
        Called by using `bot.arcadia`

        Parameters

        bot: discord.ext.commands.Bot or discord.ext.commands.AutoShardedBot
            Your Bot client from discord.py

        token: str
            Your token from eclyssia-api.tk
        """
    if hasattr(bot, 'arcadia'):
        return bot.arcadia
    bot.arcadia = cls(token, *args, bot=bot, **kwargs)
    return bot.arcadia


@classmethod
def handle_fork(cls):
    """
        Called after a forking.  This should cleanup any remaining reactor state
        from the parent process.
        """
    pass


def clean_question_mark(content):
    """Removes question mark strings, turning them to nulls.

    Parameters
    ----------
    content: :class:`str`
        A string to clean.

    Returns
    -------
    :class:`str`
        The string, or None if it was a question mark.
    """
    if not content:
        return None
    if '?' in content:
        return None
    return content.strip()


def get_object_string(swift, container, object_name):
    """Get the object contents as a string """
    data = swift.get_object(container, object_name)[1]
    try:
        return data.decode('utf-8')
    except AttributeError:
        return data


@classmethod
def get_observation_dims(cls, observation_shape):
    """
        Calculate observation dimension when it is flattened
        :param observation_shape:
        :return:
        """
    observation_space_size = 1
    for n in observation_shape:
        observation_space_size *= n
    return observation_space_size


def read_long(fo):
    """variable-length, zig-zag encoding."""
    c = fo.read(1)
    b = ord(c)
    n = b & 127
    shift = 7
    while b & 128 != 0:
        b = ord(fo.read(1))
        n |= (b & 127) << shift
        shift += 7
    return n >> 1 ^ -(n & 1)


def load(py_model_file):
    """
    Load a python-converted model file.

    Parameters
    ----------
    py_model_file : <string>
        Filename of a model which has already been converted into a
         python format.

    Examples
    --------
    >>> model = load('../tests/test-models/samples/teacup/teacup.py')
    """
    from .py_backend import functions
    return functions.Model(py_model_file)


@classmethod
def exact(cls, amount):
    """
        Return a :class:`.Dimension` with an exact size. (min, max and
        preferred set to ``amount``).
        """
    return cls(min=amount, max=amount, preferred=amount)


def auto_norm(value=None):
    """If `True`, when a qubit is created it will be normalize if necessary"""
    global _auto_norm
    _auto_norm = value if value in (False, True) else not _auto_norm


def vertical_inactive_link_mask(shape, node_status):
    """Array mask of vertical links that are inactive.

    Creates and returns a boolean 2D array dimensioned as the number of
    vertical links in the grid, not including the left and right boundaries.

    Parameters
    ----------
    shape : 2-element tuple of ints
        Number of rows and columns in the grid
    node_status : numpy array of bool (x # of nodes)
        False where node is a closed boundary; True elsewhere

    Returns
    -------
    (NR-1,NC-2) array of bool (NR=# of rows, NC=# of columns)
        Flags indicating whether the corresponding vertical link is inactive

    Examples
    --------
    >>> import numpy as np
    >>> from landlab.utils.structured_grid import vertical_inactive_link_mask
    >>> ns = np.ones(12, dtype=bool)  # case of no closed boundary nodes
    >>> vertical_inactive_link_mask((3,4), ns)
    array([[False, False],
           [False, False]], dtype=bool)
    >>> ns[2] = False    # node 2 is a closed boundary
    >>> vertical_inactive_link_mask((3,4), ns)
    array([[False,  True],
           [False, False]], dtype=bool)
    >>> ns[9] = False    # node 9 is also a closed boundary
    >>> vertical_inactive_link_mask((3,4), ns)
    array([[False,  True],
           [ True, False]], dtype=bool)
    """
    is_closed_node = node_status == 0
    is_closed_node.shape = shape
    inactive_outlinks = is_closed_node[:-1, 1:-1]
    inactive_inlinks = is_closed_node[1:, 1:-1]
    return inactive_outlinks | inactive_inlinks


def get_species_label(entry):
    """Get the species name of an assembly summary entry."""
    parts = entry['organism_name'].split(' ')
    if len(parts) < 2:
        return 'sp.'
    return parts[1]


def range(start, end):
    """
        Converts a start and end points of a range to a list of numbers

        Can go low to high or high to low
        """
    if end < start:
        return list(range(end, start + 1))
    return list(range(start, end + 1))


def rreplace(s, old, new, count=None):
    """
    Replace instances of `old` in `s` with `new`, starting from the right.

    This function is to `str.replace` what `str.rsplit` is to `str.split`.
    """
    return new.join(s.rsplit(old, count) if count is not None else s.rsplit
        (old))


def mark_freestyle_edge(clear: bool=False):
    """(Un)mark selected edges as Freestyle feature edges

    :param clear: Clear
    :type clear: bool
    """
    pass


def get_workflow(clspath):
    """
    Import a workflow class.
    :param clspath: class path
    :return:
    """
    modname, clsname = clspath.rsplit('.', 1)
    module = __import__(modname, fromlist=['*'])
    cls = getattr(module, clsname)
    return cls


def dict_search(d, k, v):
    """
    Search dictionary list by key and value
    :param d: dictionary list
    :param k: key
    :param v: value
    :return: the index of the first dictionary in the array with the specific key / value
    """
    for i in range(len(d)):
        if d[i][k] == v:
            return i
    return None


@staticmethod
def _query_const_from_list_subroutine(expr_list):
    """
        A sub method for _query_construction_from_list method in aiding query construction
        :param expr_list: list, relevance query list
        :return: str
        """
    interim_list = []
    interim_str = None
    for index, each_exp_list in enumerate(expr_list):
        for each_exp in each_exp_list:
            interim_list.append(each_exp)
        if index == len(expr_list) - 1:
            interim_str = '({})'.format(' OR '.join(interim_list))
    return interim_str


@classmethod
def generate(cls, partial_props=None):
    """
        Generate new connection file props from
        defaults
        """
    partial_props = partial_props or {}
    props = partial_props.copy()
    props.update(cls.DEFAULT_PROPERTIES)
    return cls(props)


def fv_multi_sub(formname, *pairs):
    """
    >> fv_multi_sub <formname> [ <pair1> [ <pair2> [ <pair3> ]]]

    Set multiple form fields (as with 'fv_multi') and then submit().
    """
    from twill3 import commands
    for p in pairs:
        fieldname, value = p.split('=', 1)
        commands.fv(formname, fieldname, value)
    commands.submit()


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 '+'


@classmethod
def set_config(mcs, config_path):
    """Set config which should be used in within Config singleton.

        :param config_path: a path to configuration that should be used
        :type config_path: str
        """
    assert mcs._instance is None
    mcs._config = config_path


def get_user(oneandone_conn, user, full_object=False):
    """
    Validates that the user exists by ID or a name.
    Returns the user if one was found.
    """
    for _user in oneandone_conn.list_users(per_page=1000):
        if user in (_user['id'], _user['name']):
            if full_object:
                return _user
            return _user['id']


def in_by_identity(lst, ob):
    """
    Returns True if ob is in lst by identity
    """
    for i in lst:
        if i is ob:
            return True
    return False


def printTime():
    """
    Small function to print the current time
    """
    import time
    print(time.strftime('%a, %d %b %Y %H:%M:%S +0000', time.localtime()))


def provider_api_authentication_default():
    """Default value for the API authentication field of a provider.

    Other keys are specific to each type:
    - token: "header" and "token"
    - oauth2: "client_id" and "client_secret"
    """
    return {'type': 'none'}


def get_current_username(request):
    """get current user username"""
    site = request.site
    return getattr(request, 'username', None) or site.config.get('users',
        'override', '') or getattr(request.session, 'username', None
        ) or request.remote_user or site.guest or None


def value_or_default(ar, default):
    """
    default is ar is None, else return the value of ar, returns ar even if ar is FALSEY
    :param ar:
    :param default:
    :return:
    """
    return default if ar is None else ar


def is_quoted(s):
    """ Returns True if the string begins and ends with quotes (single or double)

        :param s: a string
        :return: boolean
    """
    return s.startswith("'") and s.endswith("'") or s.startswith('"'
        ) and s.endswith('"')


def get_event(event_id):
    """
        Get an event from the message store.

        :param event_id:
            The identifier of the event to retrieve.

        :returns:
            A TransportEvent, or ``None`` if the event is not found.
            If async, a Deferred is returned instead.
        """


def receive_leave_group(group_state: 'GroupState'):
    """
    Received IGMP Leave packet regarding group GroupState
    """
    group_state.group_state_logger.debug(
        'Querier CheckingMembership: receive_leave_group')
    return


def getContents():
    """Return the contents of the clipboard"""


def bake_to_keyframes(frame_start: int=1, frame_end: int=250, step: int=1):
    """Bake rigid body transformations of selected objects to keyframes

    :param frame_start: Start Frame, Start frame for baking
    :type frame_start: int
    :param frame_end: End Frame, End frame for baking
    :type frame_end: int
    :param step: Frame Step, Frame Step
    :type step: int
    """
    pass


@classmethod
def from_psfrec(cls, rawfilename):
    """Compute FSF parameters from GLAO MUSE PSF reconstruction"""
    raise NotImplementedError


def _torads(in_file, fmap_range=None, newpath=None):
    """
    Convert a field map to rad/s units

    If fmap_range is None, the range of the fieldmap
    will be automatically calculated.

    Use fmap_range=0.5 to convert from Hz to rad/s
    """
    from math import pi
    import nibabel as nb
    from nipype.utils.filemanip import fname_presuffix
    out_file = fname_presuffix(in_file, suffix='_rad', newpath=newpath)
    fmapnii = nb.load(in_file)
    fmapdata = fmapnii.get_data()
    if fmap_range is None:
        fmap_range = max(abs(fmapdata.min()), fmapdata.max())
    fmapdata = fmapdata * (pi / fmap_range)
    out_img = nb.Nifti1Image(fmapdata, fmapnii.affine, fmapnii.header)
    out_img.set_data_dtype('float32')
    out_img.to_filename(out_file)
    return out_file, fmap_range


def tup(item, ret_is_single=False):
    """Forces casting of item to a tuple (for a list) or generates a
    single element tuple (for anything else)
    :param item:
    :param ret_is_single:
    """
    if hasattr(item, '__iter__'):
        return (item, False) if ret_is_single else item
    else:
        return ((item,), True) if ret_is_single else (item,)


def index_satisfying(iterable, condition):
    """Returns the index of the first element in `iterable` that
    satisfies the given condition.

    If no such element is found (that is, when the iterable is
    exhausted), this returns the length of the iterable (that is, one
    greater than the last index of the iterable).

    `iterable` must not be empty. If `iterable` is empty, this
    function raises :exc:`ValueError`.

    """
    for i, x in enumerate(iterable):
        if condition(x):
            return i
    try:
        return i + 1
    except NameError:
        raise ValueError('iterable must be non-empty')


def update_probability(prior, prob_given_true, prob_given_false):
    """Update probability using Bayes' rule."""
    numerator = prob_given_true * prior
    denominator = numerator + prob_given_false * (1 - prior)
    probability = numerator / denominator
    return probability


def parse_string(string):
    """Re-encodes strings from AFIP's weird encoding to UTF-8."""
    try:
        return string.encode('latin-1').decode()
    except UnicodeDecodeError:
        return string


def p_import_as_names_star_2(p):
    """import_as_names_star : import_as_names_star COMMA import_as_name"""
    p[0] = p[1] + [p[3]]


def mult_diag(d, mat, left=True):
    """Efficient multiply a full matrix by a diagonal matrix.

    This function should always be faster than dot.

    Parameters
    ----------
    d : 1D np.ndarray (n)
        Contains the diagonal elements.
    mat : 2D np.ndarray (n,n)
        Contains the matrix

    Returns
    --------
    res (n, n)
        Result of multiplying the matrices

    Notes
    ------
    This code by:
    Pietro Berkes berkes@gatsby.ucl.ac...
    Mon Mar 26 11:55:47 CDT 2007
    http://mail.scipy.org/pipermail/numpy-discussion/2007-March/026807.html

    Examples
    --------
    >>> mat = np.random.randn(20,20)
    >>> d = np.random.randn(20)
    >>> assert np.allclose(mult_diag(d, mat, left=True), np.dot(np.diag(d), mat))
    >>> assert np.allclose(mult_diag(d, mat, left=False), np.dot(mat, np.diag(d)))
    """
    if left:
        return (d * mat.T).T
    else:
        return d * mat


def disp_df_head_tail(df, n_head=3, n_tail=3, head_capt='df.head',
    tail_capt='df.tail'):
    """Displays the df.head(n_head) and df.tail(n_tail) and sets captions using df.style"""
    from IPython.display import display
    import pandas as pd
    df_h = df.head(n_head).style.set_caption(head_capt)
    df_t = df.tail(n_tail).style.set_caption(tail_capt)
    display(df_h, df_t)


def ensure_known(target, value, known):
    """
    Validate whether the a target argument is known and supported. The
    ``target`` is only used to provide a friendlier message to the user.
    The given ``value`` is checked against ``known`` and ``supported``.

    Args:
        target (str): name of the target, as known to the end-user.
        value (str): value of the target key.
        known (list,tuple): known possible values for the target.

    Raises:
          :class:`ValueError`: if given value is not in ``known``.
    """
    if value not in known:
        raise ValueError(f'{target}={value} must be one of {known}')


def __getitem__(index):
    """Return the header match at the given index for this mailing list.

        :param index: The index of the header match to return.
        :type index: integer
        :return: The header match at this index.
        :rtype: `IHeaderMatch`
        :raises IndexError: if there is no header match at this index for
            this mailing list.
        """


@staticmethod
def _extract_root_module(module_name):
    """Given a module name, returns only the root module by ignoring
        everything including and after the leftmost "." if one exists."""
    return module_name.split('.')[0]


def ignore(x):
    """Method to indicate bypassing property validation"""
    return x


def check_long(lng):
    """
    Checks whether the input longitude is within range and correct type

    Parameters
    ----------
    lng : float or int
        longitude (-179 to 180) in degrees

    Returns
    -------
    None. Raises an exception in case
    """
    if isinstance(lng, (int, float)):
        if abs(lng) > 180:
            raise ValueError('longitude should be -180 <= longitude <= 180')
    else:
        raise TypeError('longitude should be "float" or "int"')
    return None


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 sqrt(op):
    """
    Return the square root of a linear operator, if defined. Note that
    this is not the elementwise square root. The result is a linear operator
    that, when composed with itself, yields the original operator.
    """
    return op._sqrt()


def _get_method(request):
    """Return what's supposed to be the method for CORS operations.
    (e.g if the verb is options, look at the A-C-Request-Method header,
    otherwise return the HTTP verb).
    """
    if request.method == 'OPTIONS':
        method = request.headers.get('Access-Control-Request-Method',
            request.method)
    else:
        method = request.method
    return method


def getMemberDataContents():
    """ Returns a list containing a dictionary with information
        about the _members BTree contents

        o The key 'member_count' is the total number of member instances
          stored in the memberdata-tool

        o The key 'orphan_count' is the number of member instances
          that for are no longer in the underlying acl_users user folder.

        o The result is designed to be iterated over in a dtml-in

        o ???:  why a sequence?

        o Permission:  Private (Python-only)
        """


def add_cookbook_mgmt_options(parser):
    """Add the cookbook management command and arguments.

    :rtype: argparse.ArgumentParser

    """
    cookbook = parser.add_parser('cookbook', help=
        'Invoke in a Jenkins job to update a cookbook in chef-repo')
    cookbook.add_argument('repo', action='store', help='Git URL for chef-repo')
    cookbook.set_defaults(func='process_cookbook')


def rshift(val, n):
    """python port for '>>>'(right shift with padding)
    """
    return val % 4294967296 >> n


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


@staticmethod
def expr_linebreaks():
    """
        Converts line breaks to unix-style and removes extra breaks
        if found more than two in a row.

        >>> from typus import en_typus
        >>> en_typus('foo\\r\\nbar\\n\\n\\nbaz')
        'foo\\nbar\\n\\nbaz'
        """
    expr = ('\\r\\n', '\n'), ('\\n{2,}', '\n' * 2)
    return expr


def get_meta_graph_def(saved_model_dir, tag_set):
    """Utility function to read a meta_graph_def from disk.

  From `saved_model_cli.py <https://github.com/tensorflow/tensorflow/blob/8e0e8d41a3a8f2d4a6100c2ea1dc9d6c6c4ad382/tensorflow/python/tools/saved_model_cli.py#L186>`_

  DEPRECATED for TF2.0+

  Args:
    :saved_model_dir: path to saved_model.
    :tag_set: list of string tags identifying the TensorFlow graph within the saved_model.

  Returns:
    A TensorFlow meta_graph_def, or raises an Exception otherwise.
  """
    from tensorflow.contrib.saved_model.python.saved_model import reader
    saved_model = reader.read_saved_model(saved_model_dir)
    set_of_tags = set(tag_set.split(','))
    for meta_graph_def in saved_model.meta_graphs:
        if set(meta_graph_def.meta_info_def.tags) == set_of_tags:
            return meta_graph_def
    raise RuntimeError(
        'MetaGraphDef associated with tag-set {0} could not be found in SavedModel'
        .format(tag_set))


def str2numorstr(x, method=int):
    """
    This extracts numbers from strings. eg. 114 from M114R.

    :param x: string
    """
    try:
        x = method(x)
        return x
    except:
        return x


def query_dict_list(engine, query):
    """Get the results of a MySQL query as a list of dictionaries.

    :param engine: SQLAlchemy Engine object able to connect to a MySQL database.
    :type engine: Engine
    :param query: MySQL query statement.
    :type query: str
    :returns:
        List of dictionaries, where each dictionary represents a row of data.
    :rtype: list
    """
    result_list = engine.execute(query).fetchall()
    result_dict_list = []
    for row in result_list:
        row_as_dict = dict(row)
        result_dict_list.append(row_as_dict)
    return result_dict_list


def check(monitor, verify=False, add_lease=False):
    """Check up on my health, optionally repairing any problems.

        This returns a Deferred that fires with an instance that provides
        ICheckResults, or None if the object is non-distributed (i.e. LIT
        files).

        The monitor will be checked periodically to see if the operation has
        been cancelled. If so, no new queries will be sent, and the Deferred
        will fire (with a OperationCancelledError) immediately.

        Filenodes and dirnodes (which provide IFilesystemNode) are also
        checkable. Instances that represent verifier-caps will be checkable
        but not downloadable. Some objects (like LIT files) do not actually
        live in the grid, and their checkers return None (non-distributed
        files are always healthy).

        If verify=False, a relatively lightweight check will be performed: I
        will ask all servers if they have a share for me, and I will believe
        whatever they say. If there are at least N distinct shares on the
        grid, my results will indicate r.is_healthy()==True. This requires a
        roundtrip to each server, but does not transfer very much data, so
        the network bandwidth is fairly low.

        If verify=True, a more resource-intensive check will be performed:
        every share will be downloaded, and the hashes will be validated on
        every bit. I will ignore any shares that failed their hash checks. If
        there are at least N distinct valid shares on the grid, my results
        will indicate r.is_healthy()==True. This requires N/k times as much
        download bandwidth (and server disk IO) as a regular download. If a
        storage server is holding a corrupt share, or is experiencing memory
        failures during retrieval, or is malicious or buggy, then
        verification will detect the problem, but checking will not.

        If add_lease=True, I will ensure that an up-to-date lease is present
        on each share. The lease secrets will be derived from by node secret
        (in BASEDIR/private/secret), so either I will add a new lease to the
        share, or I will merely renew the lease that I already had. In a
        future version of the storage-server protocol (once Accounting has
        been implemented), there may be additional options here to define the
        kind of lease that is obtained (which account number to claim, etc).

        TODO: any problems seen during checking will be reported to the
        health-manager.furl, a centralized object that is responsible for
        figuring out why files are unhealthy so corrective action can be
        taken.
        """


@classmethod
def clear(cls) ->None:
    """Clears :code:`cls.all` and :code:`cls.__new`.
        """
    cls.all = dict()
    cls.__new = dict()


def concatSC(m, n, k=1):
    """Worst case state complecity for concatenation
    :arg m: number of states
    :arg n: number of states
    :arg k: number of letters
    :type m: integer
    :type n: integer
    :type k: integer
    :returns: state compelxity
    :rtype: integer"""
    return m * 2 ** n - k * 2 ** (n - 1)


def is_remote_list(values):
    """ check if this list corresponds to a backend formatted collection of
    dictionaries """
    for v in values:
        if not isinstance(v, dict):
            return False
        if '@type' not in v.keys():
            return False
    return True


@classmethod
def is_usable(cls):
    """
        Check whether this data set implementations is available for use.

        This is always true for this implementation as there are no required 3rd
        party dependencies

        :return: Boolean determination of whether this implementation is usable.
        :rtype: bool

        """
    return True


def _folium_map_formatter(map) ->str:
    """ inputs a folium.Map object and returns html of rendered map """
    import base64
    html_source = map.get_root().render()
    b64_source = base64.b64encode(bytes(html_source.encode('utf-8'))).decode(
        'utf-8')
    source_blob = (
        '<iframe src="data:text/html;charset=utf-8;base64,{}" allowfullscreen="" webkitallowfullscreen="" mozallowfullscreen="" style="position:relative;width:100%;height:500px"></iframe>'
        )
    return source_blob.format(b64_source)


def __len__():
    """Return the number of items in the container."""


@classmethod
def get_selected_path_list(cls, parse_result):
    """
        This method returns the path to the selected node as a list of name strings.

        :param argparse.Namespace parse_result: A namespace object returned by
            :py:meth:`argparse.ArgumentParser.parse_args`.
        :rtype: list
        """
    parts = []
    pdict = parse_result.__dict__
    for key, value in pdict.items():
        if value is None:
            continue
        re_result = cls._subparser_regex.match(key)
        if re_result:
            index = int(re_result.group(1))
            parts.insert(index, value)
    return parts


def generate_presigned_url(ClientMethod=None, Params=None, ExpiresIn=None,
    HttpMethod=None):
    """
    Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
            ClientMethod.

    :type ExpiresIn: int
    :param ExpiresIn: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
            default, the http method is whatever is used in the method's model.

    """
    pass


@classmethod
def add_domain(cls, options=None):
    """Associate a domain"""
    cls.command_sub = 'add-domain'
    return cls.execute(cls._construct_command(options))


def describe_locations():
    """
    Returns the list of AWS Direct Connect locations in the current AWS region. These are the locations that may be selected when calling CreateConnection or CreateInterconnect.
    See also: AWS API Documentation

    :example: response = client.describe_locations()

    :rtype: dict
    :return: {
        'locations': [
            {
                'locationCode': 'string',
                'locationName': 'string'
            },
        ]
    }

    """
    pass


@property
def fclk3_mhz(cls):
    """The getter method for PL clock 3.

        This method will read the register values, do the calculation,
        and return the current clock rate.

        Returns
        -------
        float
            The returned clock rate measured in MHz.

        """
    return cls.get_pl_clk(3)


def con5code(code):
    """
    hkcode contain 5 digitals
    series converter ,map function
    """
    if code[0] != '8':
        code = '0' + code[0:4]
    else:
        code = code[0:5]
    return code


def index_rules_by_type(rules):
    """
    Indexes a list of rules by type name,
    while maintaining rule order for each rule type

    Sample Input:
    [
        <TimeRule: Time Rule>,
        <TimeRule: Time Rule>,
        <UserIsLoggedInRule: Logged in Rule>
    ]

    Sample Output:
    {
        'TimeRule': [ <TimeRule: Time Rule>, <TimeRule: Time Rule> ],
        'UserIsLoggedInRule': [ <UserIsLoggedInRule: Logged in Rule> ]
    }
    """
    indexed_rules = {}
    for rule in rules:
        type_name = type(rule).__name__
        if type_name in indexed_rules:
            indexed_rules[type_name].append(rule)
        else:
            indexed_rules[type_name] = [rule]
    return indexed_rules


def is_leap_year(year):
    """Determine whether a year is a leap year"""
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)


def environment_from_config(config):
    """
    This functions returns either the environment of the current configuration.

    :param config: current configuration
    :return: 'staging' or 'production'
    """
    if hasattr(config, 'DEVICE_HOST') and 'test' in config.DEVICE_HOST:
        return 'staging'
    else:
        return 'production'


def clean_result_page(resultpage):
    """
    Takes the HTML output from the TMHMM result page and trims some HTML
    to make the output parsable by the existing standalone tmhmm parser.

    Returns the cleaned up result page.
    """
    resultlines = resultpage.split('\n')
    firstpreindex = 0
    for i in range(len(resultlines)):
        if '
' in resultlines[i]:
            firstpreindex = i
            break
    resultpage = '\n'.join(resultlines[firstpreindex:-3])
    resultpage = resultpage.replace('
', '\n')
    resultpage = resultpage.replace('
', '')
    resultpage = resultpage.replace('
', '')
    resultpage = resultpage.replace('
', '')
    return resultpage


def rewrite_function_name(journal_id, rewrite_type):
    """ concatenate the name of the rewriting function """
    if not journal_id or not rewrite_type:
        return None
    return 'rewrite_' + journal_id.lower() + '_' + rewrite_type


@classmethod
def from_directed_graph(cls, directed_graph):
    """ Generate an undirected graph by turning a directed graph's edges
            into undirected edges and removing duplicate edges """
    g = cls()
    for v in directed_graph.vertices:
        g.add_vertex(v.val)
    for e in directed_graph.edges:
        v_vals = e.v_from.val, e.v_to.val
        if not g.has_edge(v_vals):
            g.add_edge(v_vals)
    return g


def _validate_axis(axis, ndim):
    """Helper function to convert axis into a non-negative integer, or raise if
    it's invalid.
    """
    if axis < 0:
        axis += ndim
    if axis < 0 or axis >= ndim:
        raise ValueError('invalid axis %s' % axis)
    return axis


def line(a, b, x, y):
    """Draw line from `(a, b)` to `(x, y)`."""
    import turtle
    turtle.up()
    turtle.goto(a, b)
    turtle.down()
    turtle.goto(x, y)


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


def _check_pandas_index_arguments(index, valid):
    """Check pandas index arguments."""
    if index is None:
        return
    if isinstance(index, str):
        index = [index]
    if not isinstance(index, list):
        raise TypeError(
            'index must be `None` or a string or list of strings, got type {}.'
            .format(type(index)))
    invalid = set(index) - set(valid)
    if invalid:
        plural = ('is not a valid option', 'are not valid options')[int(len
            (invalid) > 1)]
        raise ValueError('"{}" {}. Valid index options are `None`, "{}".'.
            format('", "'.join(invalid), plural, '", "'.join(valid)))
    return index


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 process_logical(text):
    """
    Turn text into the corresponding logical.

    Arguments:
    text - text to be coerced to a logical, if a corresponding logical exists
    """
    text = str(text)
    if (text == 'true' or text == 'True' or text == 'TRUE' or text == 'T' or
        text == 't' or text == '1' or text.lower() == 'yes'):
        return True
    elif text == 'false' or text == 'False' or text == 'FALSE' or text == 'F' or text == 'f' or text == '0' or text.lower(
        ) == 'no':
        return False
    else:
        print('Input has no logical analogue.')
        return text


def response_content_is_login_page(response_content):
    """Returns True if the provided response_content seems to be from the Vilfo login page."""
    detectors = ['<title>Login | Vilfo</title>', '<Login-Form']
    detected_count = 0
    for detector in detectors:
        if detector in str(response_content):
            detected_count += 1
    return detected_count >= len(detectors) / 2


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 _get_node_type(node, potential_types):
    """
    Return the type of the node if it exists in potential_types.

    Args:
        node (astroid.node): node to get the type of.
        potential_types (tuple): potential types of the node.

    Returns:
        type: type of the node or None.
    """
    for potential_type in potential_types:
        if isinstance(node, potential_type):
            return potential_type
    return None


def hasField(name):
    """Return True if there is field called name in the schema.
        """


def select_more():
    """Select more strips adjacent to the current selection

    """
    pass


def line_indices_conservative(cell1, cell2):
    """
    Takes two cells in the grid (each described by a pair of integer
    indices), and returns a list of the cells in the grid that are on the
    line segment between the cells.  This is a conservative version.
    """
    i0, j0 = cell1
    i1, j1 = cell2
    assert type(i0) == int, 'Args to line_indices must be pairs of integers'
    assert type(j0) == int, 'Args to line_indices must be pairs of integers'
    assert type(i1) == int, 'Args to line_indices must be pairs of integers'
    assert type(j1) == int, 'Args to line_indices must be pairs of integers'
    ans = [(i0, j0)]
    di = i1 - i0
    dj = j1 - j0
    t = 0.5
    if abs(di) > abs(dj):
        m = float(dj) / float(di)
        t += j0
        if di < 0:
            di = -1
        else:
            di = 1
        m *= di
        while i0 != i1:
            i0 += di
            t1 = t + m
            if int(t1) == int(t):
                ans.append((i0, int(t1)))
            else:
                ans.append((i0 - di, int(t1)))
                ans.append((i0, int(t)))
                ans.append((i0, int(t1)))
            t = t1
    elif dj != 0:
        m = float(di) / float(dj)
        t += i0
        if dj < 0:
            dj = -1
        else:
            dj = 1
        m *= dj
        while j0 != j1:
            j0 += dj
            t1 = t + m
            if int(t1) == int(t):
                ans.append((int(t1), j0))
            else:
                ans.append((int(t1), j0 - dj))
                ans.append((int(t), j0))
                ans.append((int(t1), j0))
            t = t1
    return ans


def node_copy_color():
    """Copy color to all selected nodes

    """
    pass


def upper_first(s):
    """ uppercase first letter """
    s = str(s)
    return s[0].upper() + s[1:]


def wireframe(use_boundary: bool=True, use_even_offset: bool=True,
    use_relative_offset: bool=False, use_replace: bool=True, thickness:
    float=0.01, offset: float=0.01, use_crease: bool=False, crease_weight:
    float=0.01):
    """Create a solid wire-frame from faces

    :param use_boundary: Boundary, Inset face boundaries
    :type use_boundary: bool
    :param use_even_offset: Offset Even, Scale the offset to give more even thickness
    :type use_even_offset: bool
    :param use_relative_offset: Offset Relative, Scale the offset by surrounding geometry
    :type use_relative_offset: bool
    :param use_replace: Replace, Remove original faces
    :type use_replace: bool
    :param thickness: Thickness
    :type thickness: float
    :param offset: Offset
    :type offset: float
    :param use_crease: Crease, Crease hub edges for improved subsurf
    :type use_crease: bool
    :param crease_weight: Crease weight
    :type crease_weight: float
    """
    pass


def get_resource_and_action(action, pluralized=None):
    """Return resource and enforce_attr_based_check(boolean).

    It is per resource and action extracted from api operation.
    """
    data = action.split(':', 1)[0].split('_', 1)
    resource = pluralized or '%ss' % data[-1]
    enforce_attr_based_check = data[0] not in ('get', 'delete')
    return resource, enforce_attr_based_check


def stop_gradient(data=None, out=None, name=None, **kwargs):
    """Stops gradient computation.

    Stops the accumulated gradient of the inputs from flowing through this operator
    in the backward direction. In other words, this operator prevents the contribution
    of its inputs to be taken into account for computing gradients.

    Example::

      v1 = [1, 2]
      v2 = [0, 1]
      a = Variable('a')
      b = Variable('b')
      b_stop_grad = stop_gradient(3 * b)
      loss = MakeLoss(b_stop_grad + a)

      executor = loss.simple_bind(ctx=cpu(), a=(1,2), b=(1,2))
      executor.forward(is_train=True, a=v1, b=v2)
      executor.outputs
      [ 1.  5.]

      executor.backward()
      executor.grad_arrays
      [ 0.  0.]
      [ 1.  1.]

    Defined in src/operator/tensor/elemwise_unary_op_basic.cc:L327

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

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

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


def translate_matrix(m, v):
    """Translates a matrix by (x, y)."""
    a, b, c, d, e, f = m
    x, y = v
    return a, b, c, d, x * a + y * c + e, x * b + y * d + f


def state_str(state):
    """Return a string describing an instance via its InstanceState."""
    if state is None:
        return 'None'
    else:
        return '<%s at 0x%x>' % (state.class_.__name__, id(state.obj()))


def print_iteration(it, res, error, extra='', threshold=0.1):
    """ Checks the size of the result to select between
    scientific notation and floating point notation """
    if res < threshold:
        print(f'Result for iteration {it}: {res:.3e} +/- {error:.3e}' + extra)
    else:
        print(f'Result for iteration {it}: {res:.4f} +/- {error:.4f}' + extra)


def match_config(filters, device, kind, default):
    """
    Matches devices against multiple :class:`DeviceFilter`s.

    :param list filters: device filters
    :param Device device: device to be mounted
    :param str kind: value kind
    :param default: default value
    :returns: value of the first matching filter
    """
    while device is not None:
        for f in filters:
            if f.has_value(kind) and f.match(device):
                return f.value(kind, device)
            if f.has_value('skip') and f.match(device) and f.value('skip',
                device) in (True, 'all', kind):
                break
        device = device.partition_slave or device.luks_cleartext_slave
    return default


def get_bigram_scores(text_words, min_bgfreq=2.0):
    """
    compute scores for identifying bigrams in a collection of texts
    compute unigram and bigram frequencies (of words) and give a score for every bigram.
    depending on this score (e.g. if higher than a threshold), bigram phrases can be identified
    in the raw texts before splitting them into words
    --> once the lists of words in the text_words are replaced by appropriate bigrams, the whole thing could be repeated
        to find trigrams, etc.
    Input:
        - text_words: a list (or generator) of lists of (preprocessed) words
        - min_bgfreq: how often a bigram has to have to occur in the corpus to be recognized (if both words occur just once
                      and that in combination, it still doesn't mean it's a true phrase because we have too little observations of the words
    Returns:
        - bigram_scores: a dict with bigrams ("word1 word2") and their score
    """
    unigram_freq = {}
    bigram_freq = {}
    for wordlist in text_words:
        for i, word in enumerate(wordlist):
            try:
                unigram_freq[word] += 1.0
            except KeyError:
                unigram_freq[word] = 1.0
            if i:
                try:
                    bigram_freq['%s %s' % (wordlist[i - 1], word)] += 1.0
                except KeyError:
                    bigram_freq['%s %s' % (wordlist[i - 1], word)] = 1.0
    bigram_scores = {}
    for bigram in bigram_freq:
        if max(0.0, bigram_freq[bigram] - min_bgfreq):
            bigram_scores[bigram] = bigram_freq[bigram] / max(unigram_freq[
                bigram.split()[0]], unigram_freq[bigram.split()[1]])
    return bigram_scores


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


def tau_column(tau, k, j):
    """
    Determine the column index for the non-zero elements of the matrix for a
    particular row `k` and the value of `j` from the Dicke space.

    Parameters
    ----------
    tau: str
        The tau function to check for this `k` and `j`.

    k: int
        The row of the matrix M for which the non zero elements have
        to be calculated.

    j: float
        The value of `j` for this row.
    """
    k = k + 1
    mapping = {'tau3': k - (2 * j + 3), 'tau2': k - 1, 'tau4': k + (2 * j -
        1), 'tau5': k - (2 * j + 2), 'tau1': k, 'tau6': k + 2 * j, 'tau7':
        k - (2 * j + 1), 'tau8': k + 1, 'tau9': k + (2 * j + 1)}
    return int(mapping[tau] - 1)


def overlap(A, B):
    """
  if A is overlapping with B.
  """
    if A.chr != B.chr:
        return False
    if A.stop <= B.start:
        return False
    if B.stop <= A.start:
        return False
    return True


def get_constant(payment):
    """This should return a stoqdriver payment method constant

        :param payment: the payment whose method we shout return a stoqdrivers
                        constant
        :returns: one :class:`PaymentMethodConstant`
        """


def psi_H_Mg_HSO4_RC99(T, P):
    """c-c'-a: hydrogen magnesium bisulfate [RC99]."""
    psi = -0.027079
    valid = T == 298.15
    return psi, valid


def get_frames_index_range(filename, start, end):
    """
    returns a range of frames as numpy array. The indecies comply with scimage

    We can then supplement the above table as follows:

    Addendum to dimension names and orders in scikit-image
    Image type: 2D color video
    coordinates: (time, row, col, channel)
    """
    import cv2
    from numpy import array, zeros, nan
    vidcap = cv2.VideoCapture(filename)
    vidcap.set(cv2.CAP_PROP_POS_FRAMES, start)
    i = 0
    success, image = vidcap.read()
    arr = zeros((end - start, image.shape[0], image.shape[1], image.shape[2])
        ) * nan
    arr[i] = image
    i += 1
    while start + i < end:
        success, image = vidcap.read()
        if success:
            arr[i] = image
        i += 1
    return arr


def _fill_function(func, globals, defaults, dict):
    """ Fills in the rest of function data into the skeleton function object
        that were created via _make_skel_func().
         """
    func.__globals__.update(globals)
    func.__defaults__ = defaults
    func.__dict__ = dict
    return func


def desconectar(símismo, var_mds):
    """
        Esta función deshacer una conexión entre el modelo biofísico y el modelo DS. Se especifica la conexión por
        el nombre del variable en el modelo DS.

        Parameters
        ----------
        var_mds: str
            El nombre del variable conectado en el modelo DS.

        """
    símismo.desconectar_vars(var_fuente=var_mds, modelo_fuente=símismo.mds)


def prune_distribution_formats(formats):
    """derive a unique list of distribution formats"""
    counter = 0
    formats_ = []
    unique_formats = []
    for k1, v1 in formats.items():
        row = {}
        for k2, v2 in v1.items():
            if k2.startswith('format'):
                row[k2] = v2
        formats_.append(row)
    num_elements = len(formats)
    for f in range(0, len(formats_)):
        counter += 1
        if formats_[f] not in unique_formats:
            unique_formats.append(formats_[f])
        if num_elements == counter:
            break
    return unique_formats


def _seek_generator(f):
    """Yields seek position for each line.

    Args:
        f (file): the file object

    """
    yield 0
    for line in f:
        yield f.tell()


@classmethod
def from_api_response(cls, reddit_session, json_dict):
    """Return an instance of the appropriate class from the json_dict."""
    parts = reddit_session._request_url.split('/', 6)
    subreddit = parts[4]
    page = parts[6].split('.', 1)[0]
    return cls(reddit_session, subreddit, page, json_dict=json_dict)


def _compute_notebook_server_base_url():
    """Figure out the base_url of the current Jupyter notebook server.

    Copied from
    https://github.com/jupyter/notebook/issues/3156#issuecomment-401119433
    with miniscule changes. This is gross, but appears to be the best
    available option right now.

    """
    import ipykernel
    import json
    from notebook.notebookapp import list_running_servers
    import re
    import requests
    kernel_id = re.search('kernel-(.*).json', ipykernel.connect.
        get_connection_file()).group(1)
    for s in list_running_servers():
        response = requests.get(requests.compat.urljoin(s['url'],
            'api/sessions'), params={'token': s.get('token', '')})
        for n in json.loads(response.text):
            if n['kernel']['id'] == kernel_id:
                return s['base_url']
    raise Exception(
        'cannot locate our notebook server; is this code running in a Jupyter kernel?'
        )


def _get_string(src_proto, dst_dict, attr_name):
    """ Getter for a string """
    dst_dict[attr_name] = str(getattr(src_proto, attr_name))


def sortkey(item):
    """ Sorting key function that is robust to different types

    Both strings and tuples are common key types in dask graphs.
    However In Python 3 one can not compare strings with tuples directly.
    This function maps many types to a form where they can be compared

    Examples
    --------
    >>> sortkey('Hello')
    ('str', 'Hello')

    >>> sortkey(('x', 1))
    ('tuple', ('x', 1))
    """
    return type(item).__name__, item


def bet_size_sigmoid(w_param, price_div):
    """
    Part of SNIPPET 10.4
    Calculates the bet size from the price divergence and a regulating coefficient.
    Based on a sigmoid function for a bet size algorithm.

    :param w_param: (float) Coefficient regulating the width of the bet size function.
    :param price_div: (float) Price divergence, forecast price - market price.
    :return: (float) The bet size.
    """
    return price_div * (w_param + price_div ** 2) ** -0.5


def ModuleSelectionImprovable(TaskGraph, CurSched):
    """
	return True if module selection is improvable
	"""
    if len(CurSched) == 0:
        return True
    else:
        return False


def menus():
    """Return dict of menus"""
    items = ['home', 'create', 'approve', 'assign', 'batches']
    return items


def read_namespace_file(package):
    """Parses NAMESPACE file for exports

    :param: package: string for the package name
    :return: list of exports
    """
    inner_list = []
    namespace_file = f'{package}/NAMESPACE'
    try:
        with open(namespace_file, 'r', encoding='ISO-8859-1') as nmspc_file:
            for i in nmspc_file:
                if i.startswith('export('):
                    func = i[len('export('):]
                    func = func.rstrip(')\n')
                    inner_list.append(func)
    except FileNotFoundError:
        return inner_list
    return inner_list


@classmethod
def _map_claim_name_to_instance_var(cls, claim_name: str) ->str:
    """
            Map a claim to the name of its instance variable.

            :param claim_name: The name of the claim to map.
            :return: The name of the corresponding instance variable.
        """
    return cls._instance_var_claim_name_mapping.inv.get(claim_name, claim_name)


def normalize_path(path):
    """
    Add slash to path end
    """
    if path[-1] != '/':
        return path + '/'
    return path


def urlify(s):
    """
    Turn plot title into filename for saving
    """
    import re
    s = s.lower()
    s = re.sub('[^\\w\\s-]', '', s)
    s = re.sub('\\s+', '-', s)
    s = re.sub('-(textbf|emph|textsc|textit)', '-', s)
    return s


def nmap_service_loopy(host, args, addr, data_nmap_services):
    """
    Specific Nmap loop to print all identified services, if stored in the XML
    """
    for port in host.findall('ports/port'):
        portid = port.get('portid')
        for root_state in port.findall('state'):
            if root_state.get('state') == args.nmap_state:
                for service in port.findall('service'):
                    proto = port.get('protocol')
                    service_name = service.get('name')
                    state = root_state.get('state')
                    data_nmap_services.append([addr, portid, proto,
                        service_name, state])


def _check_duplicate(list_to_check) ->bool:
    """
    Check if a list has duplicate
    :param list_to_check: the list to check
    :return: True if the list has duplicate values
    """
    return len(set(list_to_check)) == len(list_to_check)


@classmethod
def topic(cls, **kwargs) ->str:
    """Get MQTT topic for this message type."""
    return 'hermes/error/tts'


def scan_setup_py():
    """Validate the contents of setup.py against Versioneer's expectations."""
    found = set()
    setters = False
    errors = 0
    with open('setup.py', 'r') as f:
        for line in f.readlines():
            if 'import versioneer' in line:
                found.add('import')
            if 'versioneer.get_cmdclass()' in line:
                found.add('cmdclass')
            if 'versioneer.get_version()' in line:
                found.add('get_version')
            if 'versioneer.VCS' in line:
                setters = True
            if 'versioneer.versionfile_source' in line:
                setters = True
    if len(found) != 3:
        print('')
        print('Your setup.py appears to be missing some important items')
        print('(but I might be wrong). Please make sure it has something')
        print('roughly like the following:')
        print('')
        print(' import versioneer')
        print(' setup( version=versioneer.get_version(),')
        print('        cmdclass=versioneer.get_cmdclass(),  ...)')
        print('')
        errors += 1
    if setters:
        print("You should remove lines like 'versioneer.VCS = ' and")
        print("'versioneer.versionfile_source = ' . This configuration")
        print('now lives in setup.cfg, and should be removed from setup.py')
        print('')
        errors += 1
    return errors


def _build_html_image(img, id, div_klass, img_klass, caption=None, show=
    True, image_format='png'):
    """Build a html image from a slice array."""
    html = []
    add_style = u'' if show else u'style="display: none"'
    html.append(u'
' % (div_klass, id, add_style))
    html.append(u'
')
    if image_format == 'png':
        html.append(
            u''
             % (img_klass, img))
    else:
        html.append(u'
%s
' %
            (img_klass, img))
    html.append(u'
')
    if caption:
        html.append(u'
%s
' % caption)
    html.append(u'
')
    return u'\n'.join(html)


def _join_translated(translated_parts, os_sep_class):
    """Join translated glob pattern parts.

    This is different from a simple join, as care need to be taken
    to allow ** to match ZERO or more directories.
    """
    res = ''
    for part in translated_parts[:-1]:
        if part == '.*':
            res += part
        else:
            res += part + os_sep_class
    if translated_parts[-1] == '.*':
        res += '.+'
        res += '({os_sep_class}?.*)?'.format(os_sep_class=os_sep_class)
    else:
        res += translated_parts[-1]
    return res


def _setup(app_obj):
    """
        The _setup function is called during application initialization and
        must 'setup' the handler object making it ready for the framework
        or the application to make further calls to it.

        :param app_obj: The application object.

        """


def _get_extension_for_entry(intake_entry):
    """
    Given an intake catalog entry, return a file extension for it, which can
    be used to construct names when re-uploading the files to s3. It would be
    nice to be able to rely on extensions in the URL, but that is not
    particularly reliable. Instead, we infer an extension from the driver and
    args that are used. The following extensions are returned:

        GeoJSON: ".geojson"
        Zipped Shapefile: ".zip"
        Shapefile: ".shp"
        CSV: ".csv"
    """
    driver = intake_entry.get('driver')
    if (driver == 'geojson' or driver ==
        'intake_geopandas.geopandas.GeoJSONSource'):
        return '.geojson'
    elif driver == 'shapefile' or driver == 'intake_geopandas.geopandas.ShapefileSource':
        return '.zip'
    elif driver == 'csv' or driver == 'intake.source.csv.CSVSource':
        return '.csv'
    else:
        raise ValueError(f'Unsupported driver {driver}')


def pred_frequencies(df):
    """Total number of occurrences of individual predictions over all frames."""
    return df.noraw.HId.value_counts()


def simple_split(string):
    """
    Same as str.split()

    Splits 'string' on whitespace. Empty strings are remove from the result.
    """
    return string.split()


def id_record(rec):
    """Converts a record's id to a blank node id and returns the record."""
    rec['id'] = '_:f%s' % rec['id']
    return rec


def byte_size(x):
    """Converts a byte size into a human-readable string.

    :type x: int
    :param x: number of bytes

    :rtype: str
    :returns: the given size formatted in a human-readable string
    """
    suffixes = ['bytes', 'KB', 'MB', 'GB', 'TB']
    index = 0
    while x > 1024 and index < 4:
        index += 1
        x /= 1024
    return '{} {}'.format(int(round(x)), suffixes[index])


def importFromZip(input_archive, request, replace=False):
    """Import Silva content from a full media opened zip
        file. Optionaly replace content.
        """


def sculptmode_toggle(back: bool=False):
    """Enter/Exit sculpt mode for Grease Pencil strokes

    :param back: Return to Previous Mode, Return to previous mode
    :type back: bool
    """
    pass


def ensure_ext(filepath, ext, case_sensitive=False):
    """
    Return the path with the extension added if it is not already set.

    :arg ext: The extension to check for, can be a compound extension. Should
              start with a dot, such as '.blend' or '.tar.gz'.
    :type ext: string
    :arg case_sensitive: Check for matching case when comparing extensions.
    :type case_sensitive: bool
    """
    if case_sensitive:
        if filepath.endswith(ext):
            return filepath
    elif filepath[-len(ext):].lower().endswith(ext.lower()):
        return filepath
    return filepath + ext


def save_replace_dataset(hf, address, data, maxshape, dtype):
    """Saves or replaces a dataset in a hdf5 file. The dataset must be resizable (see the HDF5 manual).

    Parameters
    ----------
    hf : :obj:`h5py.File`
        hdf5 file (already opened with writing permission)
    address : :obj:`str`
        address of the dataset to be written/replaced
    data : array
        data to be saved
    maxshape : array or None
        maximum size of the array
    dtype : array
        data type

    """
    if address in hf:
        chunk = hf[address]
        chunk.resize(data.shape)
        chunk[...] = data
    else:
        hf.create_dataset(address, data=data, maxshape=maxshape, dtype=dtype)


def unique(lst):
    """
    Return a list without repeated entries (first occurrence is kept),
    preserving order.
    """
    seen = set()
    new_lst = []
    for item in lst:
        if item in seen:
            continue
        seen.add(item)
        new_lst.append(item)
    return new_lst


def slice(seq, indices):
    """Performs a Perl-style slice, substituting None for out-of-range
    indices rather than raising an exception.
    """
    sliced = []
    for index in indices:
        try:
            sliced.append(seq[int(index)])
        except IndexError:
            sliced.append(None)
    return sliced


@classmethod
def _import_it(cls):
    """
        Internal method - performs the import and returns the imported object.
        """
    return None


def convert_pid(value):
    """Convert pid from hex string to integer."""
    return int(value, 16)


def relu_forward(x):
    """
    Computes ReLU activation for input tensor.

    Inputs:
    - x: Input data. of arbitary shape

    Returns:
    - out: ReLU activation of x
    """
    out = x * (x > 0)
    return out


def generate_scope_string(date, region, service_name):
    """
    Generate scope string.

    :param date: Date is input from :meth:`datetime.datetime`
    :param region: Region should be set to bucket region.
    :param service_name: Service for scope string, e.g., "s3".
    """
    formatted_date = date.strftime('%Y%m%d')
    scope = '/'.join([formatted_date, region, service_name, 'aws4_request'])
    return scope


def ssim_global(x, y, k1=0.01, k2=0.03, l=1.0):
    """
    mmsim : https://ece.uwaterloo.ca/~z70wang/publications/msssim.pdf
    wiki : https://en.wikipedia.org/wiki/Structural_similarity
    https://ece.uwaterloo.ca/~z70wang/publications/ssim.pdf
    cf. other metrics
    https://pdfs.semanticscholar.org/401e/c2881b20ce7d6dc07c274a1d8f821d4c3841.pdf

    SSIM(x, y) = ((2 µx µy + c1) / (µx^2 + µy^2 + c1)) * ((2 σxy + c2) / (σx^2 + σy^2 + c2))
    todo :
    similarity between images
    considering illumination, constrast and structure of image
    if c1 = c2 = 0, then SSIM == UQI (universal quality index)

    c1 = (k1 * L)^2, c2 = (k2 * L)^2
    k1 = 0.01 and k2 = 0.03 by default
    L = dynamic range of the pixel values (typically 2^(#bits per per pixel - 1)
    c3 - c2 / 2
    :param x: image [batch, h, w, c]
    :param y: image [batch, h, w, c]
    :param c1: todo : check value in original paper
    :param c2: todo : check value in original paper
    :return: similarity
    """
    reduction_indices = 1, 2, 3
    c1 = (k1 * l) ** 2
    c2 = (k2 * l) ** 2
    mx = x.mean(axis=reduction_indices, keepdims=True)
    my = y.mean(axis=reduction_indices, keepdims=True)
    sx = x.std(axis=reduction_indices, keepdims=True)
    sy = y.std(axis=reduction_indices, keepdims=True)
    xy = (x - mx) * (y - my)
    sxy = xy.mean(axis=reduction_indices, keepdims=True)
    similarity = (2.0 * mx * my + c1) / (mx.square() + my.square() + c1)
    similarity *= (2 * sxy + c2) / (sx.square() + sy.square() + c2)
    return similarity


def chunks(l, n):
    """Yield n successive chunks from l
    """
    newn = int(len(l) / n)
    for i in range(0, n - 1):
        yield l[i * newn:i * newn + newn]
    yield l[n * newn - newn:]


def _rindex(l, value):
    """Same as str.rindex, but for lists."""
    return len(l) - l[::-1].index(value) - 1


def get_arg(args, num):
    """Returns the num value from args
    without throwing an annoying exception
    when num is too large.

    >>> get_arg([0], 0)
    0
    >>> get_arg([0], 1)
    ''
    >>> get_arg([0, 1, 2, 3], 5)
    ''
    >>> get_arg([0, 1, 2, 3], 2)
    2

    :param num:
    :return: string arg value
    """
    if len(args) >= num + 1:
        return args[num]
    else:
        return ''


def is_response_to_head(response):
    """
    Checks whether the request of a response has been a HEAD-request.
    Handles the quirks of AppEngine.

    :param conn:
    :type conn: :class:`httplib.HTTPResponse`
    """
    method = response._method
    if isinstance(method, int):
        return method == 3
    return method.upper() == 'HEAD'


def interleave_data(data):
    """
    Interleave real, imag data in data
    """
    return data.view('float32')


@classmethod
def get_name(cls):
    """ Returns the name of the supplier.

			# Return value

			A lower-case string unique to this supplier.
		"""
    return cls.__name__.lower()


@classmethod
def from_list(cls, values):
    """Construct a frame from a list of 12 or 16 float values.

        Parameters
        ----------
        values : list of float
            The list of 12 or 16 values representing a 4x4 matrix.

        Returns
        -------
        :class:`compas.geometry.Frame`
            The constructed frame.

        Raises
        ------
        ValueError
            If the length of the list is neither 12 nor 16.

        Notes
        -----
        Since the transformation matrix follows the row-major order, the
        translational components must be at the list's indices 3, 7, 11.

        Examples
        --------
        >>> l = [-1.0,  0.0,  0.0, 8110, 0.0,  0.0, -1.0, 7020, 0.0, -1.0,  0.0, 1810]
        >>> f = Frame.from_list(l)
        """
    if len(values) == 12:
        values.extend([0.0, 0.0, 0.0, 1.0])
    if len(values) != 16:
        raise ValueError('Expected 12 or 16 floats but got %d' % len(values))
    matrix = [[(0.0) for i in range(4)] for j in range(4)]
    for i in range(4):
        for j in range(4):
            matrix[i][j] = float(values[i * 4 + j])
    return cls.from_matrix(matrix)


def has_key(key):
    """Returns a boolean, True if the key exists in the dict,
        False otherwise.
        """


@classmethod
def stripe_even(cls, n_more, more_val, n_less, less_val):
    """
        Prepare striping for an even number of rows.

        :param n_more:
            The number of rows with the value that there's more of

        :param more_val:
            The value that there's more of

        :param n_less:
            The number of rows that there's less of

        :param less_val:
            The value that there's less of

        :return:
            Returns a :class:`tuple` of striped values with appropriate buffer.
        """
    total = n_more + n_less
    if total % 2:
        msg = 'Expected an even number of values, got {} + {}'.format(n_more,
            n_less)
        raise ValueError(msg)
    assert n_more >= n_less, (n_more, n_less)
    n_l_c, n_m_c = n_less, n_more
    num_div = 0
    while True:
        n_l_c, lr = divmod(n_l_c, 2)
        n_m_c, mr = divmod(n_m_c, 2)
        if lr or mr:
            break
        num_div += 1
    n_cells = 2 ** num_div
    cell_s = total // n_cells
    cell_buff = int(cell_s % 2 == 0)
    cell_s -= cell_buff
    cell_nl = n_less // n_cells
    cell_nm = cell_s - cell_nl
    if cell_nm == 0:
        stripe_cell = less_val,
    else:
        stripe_cell = cls.stripe_odd(cell_nm, more_val, cell_nl, less_val)
    unit_cell = (more_val,) * cell_buff + stripe_cell
    if num_div == 0:
        return unit_cell
    stripe_out = unit_cell * (n_cells // 2)
    return tuple(reversed(stripe_out)) + stripe_out


@classmethod
def schema_exists(cls, cur, schema_name):
    """
        Check if schema exists
        """
    cur.execute(
        "SELECT EXISTS (SELECT schema_name FROM information_schema.schemata WHERE schema_name = '{0}');"
        .format(schema_name))
    return cur.fetchone()[0]


@staticmethod
def humanize_account_number(value):
    """Convert value to human formatted account number."""
    retval = value[0:6] + '-' + str(int(value[6:]))
    return retval


def Max_Params_Calc(Power_List, EFF_List, VStack_List):
    """
    Calculate maximum overall parameters.

    :param Power_List: power list
    :type Power_List : list
    :param EFF_List: efficiency list
    :type EFF_List : list
    :param VStack_List: Vstack list
    :type VStack_List : list
    :return: {max power,max efficiency,max VStack] as list
    """
    Max_Power = max(list(filter(lambda x: x is not None, Power_List)))
    Max_EFF = EFF_List[Power_List.index(Max_Power)]
    Max_VStack = VStack_List[Power_List.index(Max_Power)]
    return {'Max_Power': Max_Power, 'Max_EFF': Max_EFF, 'Max_VStack':
        Max_VStack}


@classmethod
def add_parser(cls, subparser):
    """Create parser for command line."""
    parser = super().add_parser(subparser)
    parser.add_argument('object', nargs='*', help=
        'Object on which we should operate (project, component or translation)'
        )
    return parser


def __call__(obj):
    """Post process to obj

        :param fileobj:
        :rtype: unkown
        :return obj: post processed object
        """


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

        :param SharedFolderChangeLinkPolicyDetails val:
        :rtype: EventDetails
        """
    return cls('shared_folder_change_link_policy_details', val)


def get_website_from_host(http_host):
    """Try to find the website name from the HTTP_HOST name"""
    return http_host.split(':')[0]


def t_STRING(t):
    """\\"([^\\\\"]|(\\\\.))*\\\""""
    escaped = 0
    str = t.value[1:-1]
    new_str = ''
    for i in range(0, len(str)):
        c = str[i]
        if escaped:
            if c == 'n':
                c = '\n'
            elif c == 't':
                c = '\t'
            new_str += c
            escaped = 0
        elif c == '\\':
            escaped = 1
        else:
            new_str += c
    t.value = new_str
    return t


@staticmethod
def _readMeta(fd):
    """Read meta array from the top of a file. Read lines until a blank line is reached.
        This function should ideally work for ALL versions of MetaArray.
        """
    meta = ''
    while True:
        line = fd.readline().strip()
        if line == '':
            break
        meta += line
    ret = eval(meta)
    return ret


def google_text_emphasis(style):
    """return a list of all emphasis modifiers of the element"""
    emphasis = []
    if 'text-decoration' in style:
        emphasis.append(style['text-decoration'])
    if 'font-style' in style:
        emphasis.append(style['font-style'])
    if 'font-weight' in style:
        emphasis.append(style['font-weight'])
    return emphasis


def getTags():
    """
        Получить все текущие тэги сообщения.

        @return: список тэгов
        @rtype: C{list(str)}
        """


def find_file_in_folder(filename, foldername):
    """Finds a specific file within a folder starting from your current
    position in the directory tree.
    """
    from pathlib import Path
    p = Path('.')
    find_success = False
    if foldername is None:
        check_empty = True
        tmp_list = list(p.glob(filename))
        if len(tmp_list) == 1:
            file_path = tmp_list[0]
            print('INFO: found {0}: {1}'.format(filename, file_path.absolute())
                )
            find_success = True
        else:
            print('ERROR: no unique {} found in this directory'.format(
                filename))
    else:
        tmp_list = list(p.glob('**/' + foldername))
        check_empty = False
    if len(tmp_list) == 1 and not check_empty:
        file_list = list(p.glob(foldername + '/**/' + filename))
        if len(file_list) == 1:
            file_path = file_list[0]
            print('INFO: found {0} in {1}: {2}'.format(filename, foldername,
                file_path.absolute()))
            find_success = True
        elif len(file_list) == 0:
            print('ERROR: no {} found in this directory'.format(filename))
        else:
            print('ERROR: several {0} files in directory tree: {1}'.format(
                filename, tmp_list[0].absolute()))
    elif len(tmp_list) == 0 and not check_empty:
        print('ERROR: no {0} found in this directory tree'.format(foldername))
    elif not check_empty:
        print('ERROR: several {0} folders in directory tree: {1}'.format(
            foldername, p.absolute()))
    if not find_success:
        file_path = None
    return str(file_path.absolute())


def _raise_timeout(*args):
    """Raise global timeout exception (used by global timer)

    :param args: signal information (ignored)
    :raise KeyboardInterrupt:
    """
    raise KeyboardInterrupt('Timeout')


def face_select_linked():
    """Select linked faces

    """
    pass


@staticmethod
def for_lambda_function(function_name):
    """
        Returns the CloudWatch Log Group Name created by default for the AWS Lambda function with given name

        Parameters
        ----------
        function_name : str
            Name of the Lambda function

        Returns
        -------
        str
            Default Log Group name used by this function
        """
    return '/aws/lambda/{}'.format(function_name)


@classmethod
def clear_traces(cls):
    """Clear waveform samples from the global list of Peekers."""
    for p in cls._peekers.values():
        p.trace.clear()


def substitute_spaces(original: str, sub: str='_') ->str:
    """Substitutes spaces
    Args:
        original(str): Original string
        sub(str): Substitute
    Returns(str): String with substituted spaces
    """
    return sub.join(original.split())


def asBoolean(s):
    """Convert a string value to a boolean value."""
    ss = str(s).lower()
    if ss in ('yes', 'true', 'on'):
        return True
    elif ss in ('no', 'false', 'off'):
        return False
    else:
        raise ValueError('not a valid boolean value: ' + repr(s))


def getid(obj):
    """Wrapper to get  object's ID.

    Abstracts the common pattern of allowing both an object or an
    object's ID (UUID) as a parameter when dealing with relationships.
    """
    try:
        return obj.id
    except AttributeError:
        return obj


def count_from_0(index, collection):
    """Numbering function: consecutive integers starting at 0."""
    return index


def calculate_surface_energy(deltamux, deltamuy, x_energy, y_energy,
    xexcess, yexcess, normalised_bulk):
    """Calculates the surface for a given chemical potential of
    species x and species y for a single phase.

    .. math::
        \\gamma_{Surf} = \\frac{1}{2S} \\Bigg( E_{MO}^{slab} -
        \\frac{nCat_{Slab}}{nCat_{Bulk}} E_{MO}^{Bulk} \\Bigg) -
         \\Gamma_O \\mu_O - \\Gamma_{H_2O} \\mu_{H_2O} -
         \\Gamma_O  \\mu_O (T) - \\Gamma_{H_2O} \\mu_{H_2O} (T)

    where S is the surface area, :math:`E_{MO}^{slab}` is the DFT energy of
    the stoichiometric slab, :math:`nCat_{Slab}` is the number of cations
    in the slab, :math:`nCat_{Slab}` is the number of cations in the bulk
    unit cell, :math:`E_{MO}^{Bulk}` is the DFT energy of the bulk unit cell,
    :math:`\\Gamma_O`  :math:`\\Gamma_{H_2O}` is the excess oxygen / water at
    the surface and :math:`\\mu_O` :math:`\\mu_{H_2O}` is the oxygen /
    water chemcial potential.

    Parameters
    ----------
    deltamux : array like
        Chemical potential of species x
    deltamuy : array like
        Chemical potential of species y
    x_energy : float
        DFT energy or temperature corrected DFT energy
    y_energy : float
        DFT energy or temperature corrected DFT energy
    xexcess : float
        Surface excess of species x
    yexcess : float
        Surface excess of species y
    normalised_bulk : float
        Slab energy normalised to the bulk value.

    Returns
    -------
    array like:
        2D array of surface energies as a function of
        chemical potential of x and y
    """
    return (normalised_bulk - deltamux * xexcess - deltamuy * yexcess -
        x_energy * xexcess - y_energy * yexcess)


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 str_representer(dumper, data):
    """Use literal block scalar style for multiline strings.

    This function should be used as the `representer` argument of
    the yaml.add_representer() function before dumping the YAML.

    """
    if len(data.splitlines()) > 1:
        return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|'
            )
    return dumper.represent_scalar('tag:yaml.org,2002:str', data)


def passband_ratio(b, *args, **kwargs):
    """
    ability to constraint pblum ratios (for colors).

    This is usually passed as an argument to
     <phoebe.frontend.bundle.Bundle.add_constraint>.

    :raises NotImplementedError: because it isn't, yet
    """
    raise NotImplementedError


def copy(wave_in, wave_out, sample_count, sample_bytes):
    """Copy samples between WAV objects."""
    b_size = 65536 // sample_bytes
    while sample_count:
        b = wave_in.readframes(min(b_size, sample_count))
        b_samples = len(b) // sample_bytes
        sample_count -= b_samples
        wave_out.writeframes(b)


@classmethod
def get_option(cls, name):
    """Return included option of name.

        `name`
            Option name string.
        """
    return cls.OPTIONS.get(str(name), None)


def efit_transform(object, data):
    """Fit-Transform an object on data."""
    return object.fit_transform(data)


@classmethod
def from_file(cls, path, environ):
    """Make a Vexrc instance from given file in given environ.
        """
    instance = cls()
    instance.read(path, environ)
    return instance


def validate_maximum(value, maximum):
    """Validate that ``value`` is at most ``maximum``

    Normally called in :meth:`~mopidy.config.types.ConfigValue.deserialize`.
    """
    if maximum is not None and value > maximum:
        raise ValueError(f'{value!r} must be smaller than {maximum!r}.')


def unindex_doc(docid):
    """Remove a document from the index.

        docid: int, identifying the document

        return: None

        This call is a no-op if the docid isn't in the index, however,
        after this call, the index should have no references to the docid.
        """


@staticmethod
def set_instance_attributes(arg_dict):
    """Set attributes of the :attr:`instance` based on the given arg_dict.

        Args:
          arg_dict (dict): Dictionary of (attribute, value).
        Raises:
          InvalidInputError: if attributes are not validly set.
        """
    for arg, value in arg_dict.items():
        if arg[0].isupper() and value is not None:
            setattr(arg_dict['instance'], arg.lower(), value)
    for arg, value in arg_dict.items():
        if arg == 'instance':
            continue
        if not arg[0].isupper() and value is not None:
            setattr(arg_dict['instance'], arg, value)


@staticmethod
def JumpToken(obj, eng, callbacks, exc_info):
    """Action to take when JumpToken is raised."""
    step = exc_info[1].args[0]
    if step > 0:
        eng.state.token_pos = min(len(eng), eng.state.token_pos - 1 + step)
    else:
        eng.state.token_pos = max(-1, eng.state.token_pos - 1 + step)
    eng.state.callback_pos_reset()


def get_model(model_name):
    """
    model_name must be app.model
    """
    try:
        from django.db.models import get_model
    except:
        from django.apps import apps
        get_model = apps.get_model
    app, model = model_name.split('.')
    if not app or not model:
        raise ValueError('model_name is must be in the format app.model')
    return get_model(app, model)


def indelDelta(ref, alt):
    """ Detects the inserted or deleted bases of an indel"""
    if len(alt) > len(ref):
        return [alt.replace(ref, '', 1), str('INS')]
    elif len(alt) < len(ref):
        return [ref.replace(alt, '', 1), str('DEL')]
    else:
        return ['', '']


def integer(str_value: str, line: str) ->int:
    """casts the value as an integer"""
    try:
        value = int(str_value)
    except ValueError:
        raise ValueError('%r is not an integer; line:\n%r' % (str_value, line))
    return value


@staticmethod
def __get_dict_value(index, items):
    """Get the item from a dictionary with items"""
    if index in items.keys():
        return items[index]
    return None


def bcc_coord_test(x, y, z):
    """Test for coordinate in BCC lattice"""
    return x % 2 == y % 2 and y % 2 == z % 2


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 read_factory_settings(app_template='Template', use_empty: bool=False):
    """Load default file and user preferences

    :param use_empty: Empty
    :type use_empty: bool
    """
    pass


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

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