def restore_db_cluster_from_snapshot(AvailabilityZones=None,
    DBClusterIdentifier=None, SnapshotIdentifier=None, Engine=None,
    EngineVersion=None, Port=None, DBSubnetGroupName=None, DatabaseName=
    None, OptionGroupName=None, VpcSecurityGroupIds=None, Tags=None,
    KmsKeyId=None, EnableIAMDatabaseAuthentication=None):
    """
    Creates a new DB cluster from a DB cluster snapshot. The target DB cluster is created from the source DB cluster restore point with the same configuration as the original source DB cluster, except that the new DB cluster is created with the default security group.
    For more information on Amazon Aurora, see Aurora on Amazon RDS in the Amazon RDS User Guide.
    See also: AWS API Documentation

    Examples
    The following example restores an Amazon Aurora DB cluster from a DB cluster snapshot.
    Expected Output:

    :example: response = client.restore_db_cluster_from_snapshot(
        AvailabilityZones=[
            'string',
        ],
        DBClusterIdentifier='string',
        SnapshotIdentifier='string',
        Engine='string',
        EngineVersion='string',
        Port=123,
        DBSubnetGroupName='string',
        DatabaseName='string',
        OptionGroupName='string',
        VpcSecurityGroupIds=[
            'string',
        ],
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ],
        KmsKeyId='string',
        EnableIAMDatabaseAuthentication=True|False
    )

    :type AvailabilityZones: list
    :param AvailabilityZones: Provides the list of EC2 Availability Zones that instances in the restored DB cluster can be created in.
            (string) --

    :type DBClusterIdentifier: string
    :param DBClusterIdentifier: [REQUIRED]
            The name of the DB cluster to create from the DB cluster snapshot. This parameter isn't case-sensitive.
            Constraints:
            Must contain from 1 to 255 alphanumeric characters or hyphens
            First character must be a letter
            Cannot end with a hyphen or contain two consecutive hyphens
            Example: my-snapshot-id

    :type SnapshotIdentifier: string
    :param SnapshotIdentifier: [REQUIRED]
            The identifier for the DB cluster snapshot to restore from.
            Constraints:
            Must contain from 1 to 63 alphanumeric characters or hyphens
            First character must be a letter
            Cannot end with a hyphen or contain two consecutive hyphens

    :type Engine: string
    :param Engine: [REQUIRED]
            The database engine to use for the new DB cluster.
            Default: The same as source
            Constraint: Must be compatible with the engine of the source

    :type EngineVersion: string
    :param EngineVersion: The version of the database engine to use for the new DB cluster.

    :type Port: integer
    :param Port: The port number on which the new DB cluster accepts connections.
            Constraints: Value must be 1150-65535
            Default: The same port as the original DB cluster.

    :type DBSubnetGroupName: string
    :param DBSubnetGroupName: The name of the DB subnet group to use for the new DB cluster.
            Constraints: Must contain no more than 255 alphanumeric characters, periods, underscores, spaces, or hyphens. Must not be default.
            Example: mySubnetgroup

    :type DatabaseName: string
    :param DatabaseName: The database name for the restored DB cluster.

    :type OptionGroupName: string
    :param OptionGroupName: The name of the option group to use for the restored DB cluster.

    :type VpcSecurityGroupIds: list
    :param VpcSecurityGroupIds: A list of VPC security groups that the new DB cluster will belong to.
            (string) --

    :type Tags: list
    :param Tags: The tags to be assigned to the restored DB cluster.
            (dict) --Metadata assigned to an Amazon RDS resource consisting of a key-value pair.
            Key (string) --A key is the required name of the tag. The string value can be from 1 to 128 Unicode characters in length and cannot be prefixed with 'aws:' or 'rds:'. The string can only contain only the set of Unicode letters, digits, white-space, '_', '.', '/', '=', '+', '-' (Java regex: '^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-]*)$').
            Value (string) --A value is the optional value of the tag. The string value can be from 1 to 256 Unicode characters in length and cannot be prefixed with 'aws:' or 'rds:'. The string can only contain only the set of Unicode letters, digits, white-space, '_', '.', '/', '=', '+', '-' (Java regex: '^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-]*)$').

    :type KmsKeyId: string
    :param KmsKeyId: The KMS key identifier to use when restoring an encrypted DB cluster from a DB cluster snapshot.
            The KMS key identifier is the Amazon Resource Name (ARN) for the KMS encryption key. If you are restoring a DB cluster with the same AWS account that owns the KMS encryption key used to encrypt the new DB cluster, then you can use the KMS key alias instead of the ARN for the KMS encryption key.
            If you do not specify a value for the KmsKeyId parameter, then the following will occur:
            If the DB cluster snapshot is encrypted, then the restored DB cluster is encrypted using the KMS key that was used to encrypt the DB cluster snapshot.
            If the DB cluster snapshot is not encrypted, then the restored DB cluster is encrypted using the specified encryption key.

    :type EnableIAMDatabaseAuthentication: boolean
    :param EnableIAMDatabaseAuthentication: A Boolean value that is true to enable mapping of AWS Identity and Access Management (IAM) accounts to database accounts, and otherwise false.
            Default: false

    :rtype: dict
    :return: {
        'DBCluster': {
            'AllocatedStorage': 123,
            'AvailabilityZones': [
                'string',
            ],
            'BackupRetentionPeriod': 123,
            'CharacterSetName': 'string',
            'DatabaseName': 'string',
            'DBClusterIdentifier': 'string',
            'DBClusterParameterGroup': 'string',
            'DBSubnetGroup': 'string',
            'Status': 'string',
            'PercentProgress': 'string',
            'EarliestRestorableTime': datetime(2015, 1, 1),
            'Endpoint': 'string',
            'ReaderEndpoint': 'string',
            'MultiAZ': True|False,
            'Engine': 'string',
            'EngineVersion': 'string',
            'LatestRestorableTime': datetime(2015, 1, 1),
            'Port': 123,
            'MasterUsername': 'string',
            'DBClusterOptionGroupMemberships': [
                {
                    'DBClusterOptionGroupName': 'string',
                    'Status': 'string'
                },
            ],
            'PreferredBackupWindow': 'string',
            'PreferredMaintenanceWindow': 'string',
            'ReplicationSourceIdentifier': 'string',
            'ReadReplicaIdentifiers': [
                'string',
            ],
            'DBClusterMembers': [
                {
                    'DBInstanceIdentifier': 'string',
                    'IsClusterWriter': True|False,
                    'DBClusterParameterGroupStatus': 'string',
                    'PromotionTier': 123
                },
            ],
            'VpcSecurityGroups': [
                {
                    'VpcSecurityGroupId': 'string',
                    'Status': 'string'
                },
            ],
            'HostedZoneId': 'string',
            'StorageEncrypted': True|False,
            'KmsKeyId': 'string',
            'DbClusterResourceId': 'string',
            'DBClusterArn': 'string',
            'AssociatedRoles': [
                {
                    'RoleArn': 'string',
                    'Status': 'string'
                },
            ],
            'IAMDatabaseAuthenticationEnabled': True|False,
            'ClusterCreateTime': datetime(2015, 1, 1)
        }
    }

    :returns:
    CreateDBCluster
    DeleteDBCluster
    FailoverDBCluster
    ModifyDBCluster
    RestoreDBClusterFromSnapshot
    RestoreDBClusterToPointInTime

    """
    pass


def p_function(p):
    """function : ONEWAY function_type IDENTIFIER '(' field_seq ')' throws
                | ONEWAY function_type IDENTIFIER '(' field_seq ')'
                | function_type IDENTIFIER '(' field_seq ')' throws
                | function_type IDENTIFIER '(' field_seq ')' """
    if p[1] == 'oneway':
        oneway = True
        base = 1
    else:
        oneway = False
        base = 0
    if p[len(p) - 1] == ')':
        throws = []
    else:
        throws = p[len(p) - 1]
    p[0] = [oneway, p[base + 1], p[base + 2], p[base + 4], throws]


@classmethod
def vm_ip(cls, vm_id):
    """Return the first usable ip address for this vm.
        Returns a (version, ip) tuple."""
    vm_info = cls.info(vm_id)
    for iface in vm_info['ifaces']:
        if iface['type'] == 'private':
            continue
        for ip in iface['ips']:
            return ip['version'], ip['ip']


@classmethod
def get_auto_web_noti_tmpl(cls):
    """
        Use this method to get the tmpl you need to create in order to use
        the auto-generated tmpl path. Examples:

        >>> model = YourNotiClass
        >>> model.get_auto_web_noti_tmpl()

        """
    template = '%s/templates/%s/includes/%s%s' % (cls._meta.app_label, cls.
        _meta.app_label, cls.model_tmpl_part, cls.web_noti_tmpl_suffix)
    return template


def separate_dfs(df_holdout, treatment_col_name, outcome_col_name, covs_include
    ):
    """
    This function serves to create the control/treatment dfs for use
    in the decide_drop functions in flame and in dame.
    """
    X_treated = df_holdout.loc[df_holdout[treatment_col_name] == 1,
        df_holdout.columns.difference([outcome_col_name, treatment_col_name
        ] + list(covs_include))]
    X_control = df_holdout.loc[df_holdout[treatment_col_name] == 0,
        df_holdout.columns.difference([outcome_col_name, treatment_col_name
        ] + list(covs_include))]
    Y_treated = df_holdout.loc[df_holdout[treatment_col_name] == 1,
        outcome_col_name]
    Y_control = df_holdout.loc[df_holdout[treatment_col_name] == 0,
        outcome_col_name]
    if len(X_treated) == 0 or len(X_control) == 0 or len(Y_treated
        ) == 0 or len(Y_control) == 0 or len(X_treated.columns) == 0 or len(
        X_control.columns) == 0:
        return False, False, False, False
    return X_treated, X_control, Y_treated, Y_control


def select_border(gesture_mode: int=0, xmin: int=0, xmax: int=0, ymin: int=
    0, ymax: int=0, extend: bool=True, axis_range: bool=False):
    """Select all keyframes within the specified region

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


def net_radiation_canopy(rn_24, sf_soil):
    """
    Computes the net radiation for the canopy

    .. math ::
        Q^{*}_{canopy} = \\left(1-s_f\\right) Q^{*}

    Parameters
    ----------
    rn_24 : float
        net radiation
        :math:`Q^{*}`
        [Wm-2]
    sf_soil : float
        soil fraction
        :math:`s_f`
        [-]

    Returns
    -------
    rn_24_canopy : float
        net radiation for the canopy
        :math:`Q^{*}_{canopy}`
        [Wm-2]

    Examples
    --------
    >>> import ETLook.radiation as rad
    >>> rad.net_radiation_canopy(rn_24=200, sf_soil=0.4)
    120.0

    """
    return rn_24 * (1 - sf_soil)


def _af_parity(pi):
    """
    Computes the parity of a permutation in array form.

    The parity of a permutation reflects the parity of the
    number of inversions in the permutation, i.e., the
    number of pairs of x and y such that x > y but p[x] < p[y].

    Examples
    ========

    >>> from sympy.combinatorics.permutations import _af_parity
    >>> _af_parity([0, 1, 2, 3])
    0
    >>> _af_parity([3, 2, 0, 1])
    1

    See Also
    ========

    Permutation
    """
    n = len(pi)
    a = [0] * n
    c = 0
    for j in range(n):
        if a[j] == 0:
            c += 1
            a[j] = 1
            i = j
            while pi[i] != j:
                i = pi[i]
                a[i] = 1
    return (n - c) % 2


def _add_update_edges(graph, nodes_from, nodes_to, attr_dict=None):
    """Adds/updates edges from nodes to other nodes in the specified graph.

    It will connect the 'nodes_from' to the 'nodes_to' if an edge currently
    does *not* exist (if it does already exist then the edges attributes
    are just updated instead). When an edge is created the provided edge
    attributes dictionary will be applied to the new edge between these two
    nodes.
    """
    for u in nodes_from:
        for v in nodes_to:
            if not graph.has_edge(u, v):
                if attr_dict:
                    graph.add_edge(u, v, attr_dict=attr_dict.copy())
                else:
                    graph.add_edge(u, v)
            elif attr_dict:
                graph.add_edge(u, v, attr_dict=attr_dict.copy())


def add_tags(LoadBalancerNames=None, Tags=None):
    """
    Adds the specified tags to the specified load balancer. Each load balancer can have a maximum of 10 tags.
    Each tag consists of a key and an optional value. If a tag with the same key is already associated with the load balancer, AddTags updates its value.
    For more information, see Tag Your Classic Load Balancer in the Classic Load Balancer Guide .
    See also: AWS API Documentation

    Examples
    This example adds two tags to the specified load balancer.
    Expected Output:

    :example: response = client.add_tags(
        LoadBalancerNames=[
            'string',
        ],
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    )

    :type LoadBalancerNames: list
    :param LoadBalancerNames: [REQUIRED]
            The name of the load balancer. You can specify one load balancer only.
            (string) --

    :type Tags: list
    :param Tags: [REQUIRED]
            The tags.
            (dict) --Information about a tag.
            Key (string) -- [REQUIRED]The key of the tag.
            Value (string) --The value of the tag.

    :rtype: dict
    :return: {}

    """
    pass


def mask_hash(hash, show=6, char='*'):
    """
    Returns the given hash, with only the first ``show`` number shown. The
    rest are masked with ``char`` for security reasons.
    """
    masked = hash[:show]
    masked += char * len(hash[show:])
    return masked


@classmethod
def get_name(cls):
    """
        Returns the name of the render class without its prefix
        """
    return str(cls.__name__).replace('Renderer', '').lower()


def loads(data):
    """Loads scheduler from string."""
    del data
    assert False, 'not implemented.'


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


def ceildiv(a, b):
    """Integer ceiling division"""
    return -(-a // b)


@staticmethod
def ctrl(char):
    """
        Calculate the control code for a given key.  For example, this converts
        "a" to 1 (which is the code for ctrl-a).

        :param char: The key to convert to a control code.
        :return: The control code as an integer or None if unknown.
        """
    if not isinstance(char, int):
        char = ord(char.upper())
    return char & 31 if 64 <= char <= 95 else None


def compile_bc_Livneh2013_locations(maptable):
    """
    Compile a list of file URLs for bias corrected Livneh et al. 2013 (CIG)

    maptable: (dataframe) a dataframe that contains the FID, LAT, LONG_, and ELEV for each interpolated data file
    """
    locations = []
    for ind, row in maptable.iterrows():
        basename = '_'.join(['data', str(row['LAT']), str(row['LONG_'])])
        url = [
            'http://cses.washington.edu/rocinante/Livneh/bcLivneh_WWA_2013/forcings_ascii/'
            , basename]
        locations.append(''.join(url))
    return locations


def identity_mapper(k, v):
    """
    This is the identity mapper, just lets (k, v) pass to the next phase
    :param k: key
    :param v: value
    :return: (k,v) as a pair
    """
    return k, v


@classmethod
def make2d(cls, mx):
    """Transform matrix `mx` to be 2-dimensional"""
    raise NotImplementedError


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 _read_uint(file_handle, data_size):
    """
    Read an unsigned integer of defined data_size from file.

    :param file_handle: The file handle to read from at current position

    :param data_size: The data size in bytes of the integer to read

    :returns: The integer read and decoded
    """
    return int.from_bytes(file_handle.read(data_size), byteorder='little',
        signed=False)


def str_to_two_byte_iter(string):
    """
    Return a iter consisting of two byte chars from a string.
    """
    bstring = string.encode()
    bytes = bytearray()
    for char in bstring:
        bytes.append(char)
        bytes.append(0)
    return bytes


def set_shockwave_flash(shockwave):
    """
        set_shockwave_flash

        Set the Shockwave Flash version (supported versions: 8, 9, 10, 11, 12)

        @param shockwave: Shockwave Flash version
        @type shockwave: C{str}
        @return: None
        """


@staticmethod
def _float_converter(value: str) ->float:
    """
        Converts a string to a float
        :param value: string value
        :return: float
        """
    if '%' == value[-1]:
        return float(value[:-1]) / 100.0
    else:
        return float(value)


@classmethod
def get_address(cls, address):
    """ Maps address to (host, port) tuple. """
    if not isinstance(address, (list, tuple)):
        addr = cls.ADDRESSES.get(address)
        if addr is None:
            raise ValueError('Unknown address mapping: {0}'.format(address))
        address = addr
    return address


def load_csv_rrs(filepath, sep=','):
    """ Read data in from given filepath and return a list of integer RRs points.

    :param filepath: (str) abosolute or relative path to file containing RRs
    :param sep: (str) separator between RR numbers [default: newline]
    :return rrs: (list) integers
    """
    values = []
    for item in open(filepath).read().split('\n'):
        try:
            values.append(float(item.split(sep)[0]))
        except (ValueError, TypeError, IndexError):
            pass
    return values


@classmethod
def from_golix(cls, golix_obj):
    """ Convert the golix object to a lightweight representation.
        """
    return cls(ghid=golix_obj.ghid, recipient=golix_obj.recipient)


def hmsm_to_days(hour=0, min=0, sec=0, micro=0):
    """
    Convert hours, minutes, seconds, and microseconds to fractional days.

    Parameters
    ----------
    hour : int, optional
        Hour number. Defaults to 0.

    min : int, optional
        Minute number. Defaults to 0.

    sec : int, optional
        Second number. Defaults to 0.

    micro : int, optional
        Microsecond number. Defaults to 0.

    Returns
    -------
    days : float
        Fractional days.

    Examples
    --------
    >>> hmsm_to_days(hour=6)
    0.25

    """
    days = sec + micro / 1000000.0
    days = min + days / 60.0
    days = hour + days / 60.0
    return days / 24.0


def address_type(address):
    """
    Return the types of the address

    This can be 'AF_INET', 'AF_UNIX', or 'AF_PIPE'
    """
    if type(address) == tuple:
        return 'AF_INET'
    elif type(address) is str and address.startswith('\\\\'):
        return 'AF_PIPE'
    elif type(address) is str:
        return 'AF_UNIX'
    else:
        raise ValueError('address type of %r unrecognized' % address)


def subdivide(number_cuts: int=1):
    """Subdivide selected segments

    :param number_cuts: Number of cuts
    :type number_cuts: int
    """
    pass


def _check_proc_keys(merged_procs_par, schema):
    """Diagnostic for _assign_proc_keys."""
    crit1 = merged_procs_par['TimeGenerated_orig_par'].isin(merged_procs_par
        [schema.time_stamp])
    crit2 = merged_procs_par['EffectiveLogonId'].isin(merged_procs_par[
        schema.logon_id])
    if schema.target_logon_id:
        c2a = merged_procs_par['EffectiveLogonId'].isin(merged_procs_par[
            schema.target_logon_id])
    crit3 = merged_procs_par['parent_proc_lc'].isin(merged_procs_par[
        'new_process_lc'])
    crit4 = merged_procs_par[schema.process_id].isin(merged_procs_par[
        schema.parent_id])
    crit5 = merged_procs_par['parent_key'].isin(merged_procs_par.index)
    crit6 = merged_procs_par['parent_key'].isna()
    print('has parent time', len(merged_procs_par[crit1]))
    print('effectivelogonId in subjectlogonId', len(merged_procs_par[crit2]))
    if schema.target_logon_id:
        print('effectivelogonId in targetlogonId', len(merged_procs_par[c2a]))
    print('parent_proc_lc in procs', len(merged_procs_par[crit3]))
    print('ProcessId in ParentProcessId', len(merged_procs_par[crit4]))
    print('Parent_key in proc_key', len(merged_procs_par[crit5]))
    print('Parent_key not in proc_key', len(merged_procs_par[~crit5]))
    print('Parent_key is NA', len(merged_procs_par[crit6]))


@classmethod
def _is_factory(cls, typeobj):
    """
        Determine if typeobj is a factory for producing complex types
        """
    if hasattr(typeobj, 'Build'):
        return True
    return False


def _check_same_symbol_type(symbols):
    """Check whether all the symbols in the list are of the same type.
    Raise type error if the types are different. Return the class of
    the symbols."""
    from ..symbol.numpy import _Symbol as np_symbol
    from ..symbol import Symbol as nd_symbol
    is_np_sym = isinstance(symbols[0], np_symbol)
    for s in symbols[1:]:
        if is_np_sym != isinstance(s, np_symbol):
            raise TypeError(
                'Found both classic symbol (mx.sym.Symbol) and numpy symbol (mx.sym.np._Symbol) in outputs. This will prevent you from building a computation graph by grouping them since different types of symbols are not allowed to be grouped in Gluon to form a computation graph. You will need to convert them to the same type of symbols, either classic or numpy following this rule: if you want numpy ndarray output(s) from the computation graph, please convert all the classic symbols in the list to numpy symbols by calling `as_np_ndarray()` on each of them; if you want classic ndarray output(s) from the computation graph, please convert all the numpy symbols in the list to classic symbols by calling `as_nd_ndarray()` on each of them.'
                )
    return np_symbol if is_np_sym else nd_symbol


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

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

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


def initializer(terminating_):
    """ Method to make terminating a global variable so that it is inherited
        by child processes.
    """
    global terminating
    terminating = terminating_


@staticmethod
def evaluate(x, factor):
    """One dimensional multiply model function"""
    return factor * x


def unsmoothable_column_threshold_heuristic(window_width, bin_step):
    """
    This function defines the heuristic that determines how long a run of
    fragment-less bins must be before it is considered "unsmoothable".

    Parameters
    ----------
    window_width : int
        The width of the filtering window in base pairs.
    bin_step : int
        The "sampling rate" or "bin step".

    Returns
    -------
    int
        The maximum length of a run of fragment-less bins must be before it is
        considered "unsmoothable".
    """
    return window_width / 2 / bin_step + 1


@staticmethod
def _calc_steps(shape):
    """Returns steps of shape.

        Step is used to create an 1-dim index from n-dim index like

        >>> steps = Array._calc_steps(shape)
        >>> one_dim_index = sum(step * i for step, i in zip(steps, n_dim_index))
        """
    steps = []
    tmp_d = 1
    for d in shape[::-1]:
        steps.append(tmp_d)
        tmp_d *= d
    steps = steps[::-1]
    return steps


def convertToBooleanString(val=None):
    """
        convertToBooleanString - Converts a value to either a string of "true" or "false"

            @param val <int/str/bool> - Value
    """
    if hasattr(val, 'lower'):
        val = val.lower()
        if val in ('false', '0'):
            return 'false'
        else:
            return 'true'
    try:
        if bool(val):
            return 'true'
    except:
        pass
    return 'false'


def _Underride(d, **options):
    """Add key-value pairs to d only if key is not in d.

    If d is None, create a new dictionary.

    d: dictionary
    options: keyword args to add to d
    """
    if d is None:
        d = {}
    for key, val in options.items():
        d.setdefault(key, val)
    return d


def strtobool(val):
    """Convert a string representation of truth to true (1) or false (0).

    True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
    are 'n', 'no', 'f', 'false', 'off', and '0'.  Raises ValueError if
    'val' is anything else.
    """
    val = val.lower()
    if val in ('y', 'yes', 't', 'true', 'on', '1'):
        return 1
    elif val in ('n', 'no', 'f', 'false', 'off', '0'):
        return 0
    else:
        raise ValueError('invalid truth value %r' % (val,))


def message(mes):
    """Dedicated print function to include in Snakefiles

    In a Snakefile, the stand print function may interfer with other process
    An example is the creation of the dag file. Not sure this is a bug but
    meanwhile, one must use this function to print information.

    This adds the // -- characters in front of the prin statements."""
    from easydev.console import purple
    print('// -- ' + purple(mes))


def rename_RGA_cols(data):
    """
    names columns of RGA data like they would be from PyExpLabSys+cinfdata
    """
    channels = data['channels']
    for channel, mass in channels.items():
        if mass + '-x' in data:
            print('WARNING: rename_RGA_cols() not copying ' + channel +
                ' to ' + mass +
                ' because there is existing data. Maybe rename_RGA_cols' +
                ' was already called, or maybe the same mass appears in multiple channels.'
                )
        else:
            data[mass + '-x'] = data['Time(s)'].copy()
            data[mass + '-y'] = data[channel].copy()
            data['col_types'][mass + '-x'] = 'MS'
            data['col_types'][mass + '-y'] = 'MS'
            data['data_cols'].add(mass + '-x')
            data['data_cols'].add(mass + '-y')
            print(channel + ' copied to ' + mass)


def describe_export_configurations(exportIds=None, maxResults=None,
    nextToken=None):
    """
    Deprecated. Use DescribeExportTasks instead.
    Retrieves the status of a given export process. You can retrieve status from a maximum of 100 processes.
    See also: AWS API Documentation

    :example: response = client.describe_export_configurations(
        exportIds=[
            'string',
        ],
        maxResults=123,
        nextToken='string'
    )

    :type exportIds: list
    :param exportIds: A unique identifier that you can use to query the export status.
            (string) --

    :type maxResults: integer
    :param maxResults: The maximum number of results that you want to display as a part of the query.

    :type nextToken: string
    :param nextToken: A token to get the next set of results. For example, if you specify 100 IDs for DescribeExportConfigurationsRequest$exportIds but set DescribeExportConfigurationsRequest$maxResults to 10, you get results in a set of 10. Use the token in the query to get the next set of 10.

    :rtype: dict
    :return: {
        'exportsInfo': [
            {
                'exportId': 'string',
                'exportStatus': 'FAILED'|'SUCCEEDED'|'IN_PROGRESS',
                'statusMessage': 'string',
                'configurationsDownloadUrl': 'string',
                'exportRequestTime': datetime(2015, 1, 1)
            },
        ],
        'nextToken': 'string'
    }

    """
    pass


def splice(stream, offset, value):
    """Splices the given value into stream at the given offset and
    returns the resulting stream (the original is unchanged)"""
    return stream[:offset] + value + stream[offset + len(value):]


def show_size(brain):
    """View size value on item
        """


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


def get_keywords():
    """Get the keywords needed to look up the version information."""
    git_refnames = '$Format:%d$'
    git_full = '$Format:%H$'
    git_date = '$Format:%ci$'
    keywords = {'refnames': git_refnames, 'full': git_full, 'date': git_date}
    return keywords


def get_snr(event):
    """Get the SNR from the LVAlert packet.

    Different groups and pipelines store the SNR in different fields.

    Parameters
    ----------
    event : dict
        Event dictionary (e.g., the return value from
        :meth:`gwcelery.tasks.gracedb.get_event`).

    Returns
    -------
    snr : float
        The SNR.

    """
    group = event['group'].lower()
    pipeline = event['pipeline'].lower()
    if group == 'cbc':
        attribs = event['extra_attributes']['CoincInspiral']
        return attribs['snr']
    elif pipeline == 'cwb':
        attribs = event['extra_attributes']['MultiBurst']
        return attribs['snr']
    elif pipeline == 'olib':
        attribs = event['extra_attributes']['LalInferenceBurst']
        return attribs['omicron_snr_network']
    else:
        raise NotImplementedError('SNR attribute not found')


@classmethod
def sorted_params(cls, params):
    """
        Sort parameters.

        works with RFC 5849 logic. params is a list of key, value pairs
        """
    if isinstance(params, dict):
        params = params.items()
    if not params:
        return params
    ordered = []
    params_sorting = []
    for i, (key, value) in enumerate(params):
        base_key = key.split('[')[0]
        params_sorting.append((base_key, value, i, key))
    for _, value, _, key in sorted(params_sorting):
        ordered.append((key, value))
    return ordered


def convert_to_nullable(input_val, cast_function):
    """For non-null input_val, apply cast_function and return result if successful; for null input_val, return None.

    Args:
        input_val (Any): The value to attempt to convert to either a None or the type specified by cast_function.
            The recognized null values are '.', None, '', and 'NULL'
        cast_function (Callable[[Any], Any]): A function to cast the input_val to some specified type; should raise an
            error if this cast fails.

    Returns:
        None if input is the null value.
        An appropriately cast value if input is not null and the cast is successful.

    Raises:
        Error: whatever error is provided by cast_function if the cast fails.
    """
    if input_val in ['.', None, '', 'NULL']:
        result = None
    else:
        result = cast_function(input_val)
    return result


def distutils_dir_name(dname):
    """Returns the name of a distutils build directory

    Parameters
    ----------
    dname : str
        Base directory name

    Returns
    -------
    Name of a distutils build directory

    """
    import sys
    import sysconfig
    f = '{dirname}.{platform}-{version[0]}.{version[1]}'
    return f.format(dirname=dname, platform=sysconfig.get_platform(),
        version=sys.version_info)


def __nonzero__():
    """return True if the queue contains more than zero items, else False.
        """


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

        :param SharedLinkShareType val:
        :rtype: EventType
        """
    return cls('shared_link_share', val)


@classmethod
def from_moneyline_odds_against(cls, numerator=0, denominator=None):
    """Create a probability from moneyline odds against."""
    n, d = cls._format_moneyline(numerator, denominator)
    return cls(d, n + d)


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


def point2inch(npt, dpi=72.0):
    """
     Point to inch converter.

     :param npt: number of points
     :type npt: integer
     :return: number of inches corresponding to :param:`npt`
     :type: double
     """
    return 1.0 * npt / dpi


def _import_mpl():
    """This function is not needed outside this utils module."""
    try:
        import matplotlib.pyplot as plt
    except:
        raise ImportError('Matplotlib is not found.')
    return plt


def generate_express_checkout_rediret_url(token):
    """ create a redirect url for client with express checkout """


@classmethod
def start(cls, now, number, **options):
    """
        Return the starting datetime: ``number`` of months before ``now``.
        """
    year = now.year
    month = now.month - number + 1
    if month < 0:
        year = year + month // cls.MONTHS_IN_YEAR
        month = month % cls.MONTHS_IN_YEAR
    if month == 0:
        year = year - 1
        month = 12
    return cls.mask(now, **options).replace(year=year, month=month)


@staticmethod
def lowercase_keys(mapping):
    """Converts the values of the keys in mapping to lowercase."""
    items = mapping.items()
    for key, value in items:
        del mapping[key]
        mapping[key.lower()] = value


def format_port(port):
    """Render port option."""
    return port and '-p {}'.format(port) or ''


def qual(obj):
    """
    Return fully qualified name of a class.
    """
    return u'{}.{}'.format(obj.__class__.__module__, obj.__class__.__name__)


@classmethod
def render(cls, value, token, nomenclate_object, config_query_path=None,
    return_type=list, use_value_in_query_path=True, **kwargs):
    """ Default renderer for a token.  It checks the config for a match, if not found it uses the value provided.

        :param value: str, value we are trying to match (or config setting for the token)
        :param token: str, token we are searching for
        :param nomenclate_object: nomenclate.core.nomenclate.Nomenclate, instance of nomenclate object to query
        :param kwargs: any config settings that relate to the token as found from the nomenclate instance
        :return: str, the resulting syntactically rendered string
        """
    if config_query_path == None:
        config_query_path = nomenclate_object.OPTIONS_PATH + [token]
        if use_value_in_query_path:
            config_query_path += [value]
    config_matches = cls.get_config_match(value, config_query_path,
        return_type, nomenclate_object, **kwargs)
    options = cls.flatten_input(config_matches, value)
    option = cls.process_criteria(token, options, **kwargs
        ) if options else value
    return cls.process_token_augmentations(option, token_attr=getattr(
        nomenclate_object, token))


def getGetText(session, url, headers={}, params={}, data={}, jsons={},
    encoding='utf-8'):
    """ 获取Get请求的response.text """
    if jsons:
        res = session.get(url, headers=headers, json=jsons)
    else:
        res = session.get(url, headers=headers, params=params, data=data)
    res.encoding = encoding
    return res.text


def last_valid(objects):
    """Return last object not marked for removal"""
    for obj in reversed(objects):
        if not obj.remove:
            return obj
    return None


def reload():
    """Reload active text data-block from its file

    """
    pass


@staticmethod
def p_group_optional_list(p):
    """group_optional_list : group_optional
                               | group_optional group_optional_list"""
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


def int2str(n, length=-1):
    """Convert an integer to a byte string.

    @param n: positive integer to convert
    @param length: minimum length
    @return: converted bytestring, of at least the minimum length if it was
        specified
    """
    assert n >= 0
    r = bytearray()
    while length < 0 or len(r) < length:
        r.append(n & 255)
        n >>= 8
        if length < 0 and n == 0:
            break
    r.reverse()
    assert length < 0 or len(r) == length
    return r


def version():
    """
  show version info.
  """
    print('wbsv 0.1.6')


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 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 open_in_browser(html):
    """
    Open the HTML document in a web browser, saving it to a temporary
    file to open it.  Note that this does not delete the file after
    use.  This is mainly meant for debugging.
    """
    import os
    import webbrowser
    import tempfile
    handle, fn = tempfile.mkstemp(suffix='.html')
    f = os.fdopen(handle, 'wb')
    try:
        f.write(b"<meta charset='UTF-8' />")
        f.write(html.encode('utf-8'))
    finally:
        f.close()
    url = 'file://' + fn.replace(os.path.sep, '/')
    webbrowser.open(url)
    return url


@staticmethod
def operations(nsteps):
    """Returns the number of operations needed for nsteps of the solver.

        :param nsteps: number of steps.

        :returns: a dictionary with the same keys as the timings parameter.
          Each value is the number of operations of the corresponding type for
          ``nsteps`` iterations of the method.
        """
    raise NotImplementedError(
        'operations() has to be overridden by the derived solver class.')


def extract_value(obj):
    """This is to handle the extraction from nested vs. flat JSON.

    Args:
        obj (:py:obj): Object that may contain value in a nested or flat way.

    Returns:
        obj (:py:obj): Value extracted from object.
    """
    return obj['value'] if isinstance(obj, dict) and 'value' in obj else obj


def get_last_package_name(name):
    """
    Returns module name.

    From `a.b.c` it returns `c`.

    :param str name: Full module name
    :return: Last package name / module name.
    :rtype: str
    """
    return name.split('.')[-1]


def get_resource_id(resource):
    """
    Get a resource's ID.

    Args:
        resource (obj): a Python object.

    Returns:
        str: the resource's ID or None.
    """
    if hasattr(resource, 'resource_id'):
        attr = resource.resource_id
        if callable(attr):
            return attr()
        return attr
    elif hasattr(resource, 'id'):
        return resource.id
    return None


@classmethod
def error_label_containing(cls, text):
    """Returns an XPath to find a Label containing the error message in `text`."""
    return cls('//label[@class="error" and contains(node(),"%s")]' % text)


def normalize_sizes(sizes, dx, dy):
    """
    Return list of normalized values corresponding to a list of supplied values
    and specified width (dx)/ height (dy) dimensions.

    :param sizes: Ordered (desc) list of values to be plotted as treemap squares
    :param dx: Total treemap width
    :param dy: Total treemap height
    :return: List of normalized values corresponding to original list
    """
    total_size = sum(sizes)
    total_area = dx * dy
    sizes = map(float, sizes)
    sizes = map(lambda size: size * total_area / total_size, sizes)
    return list(sizes)


def ndim(spacy_nlp: 'Language') ->int:
    """Number of features used to represent a document / sentence."""
    return spacy_nlp.vocab.vectors_length


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 _default_callback(msg_type, message, timestamp):
    """
        This default callback function does nothing. It can be replaced via
        the `callback` parameter to the constructor
        :param msg_type:  The type of message passed to the callback function.
                          It's always one of the types in the enum at the top
                          of this file
        :param message:   A str representing a log message emitted from the SDK
                          regarding an event that has occurred
        :param timestamp: A datetime object representing the time when the event
                          occurred

        """
    return


def permute_by_workload(specs):
    """
    This is that "classic" implementation that executes all iterations of a
    workload spec before proceeding onto the next spec.

    """
    for spec in specs:
        for i in range(1, spec.iterations + 1):
            yield spec, i


def split_role(r):
    """
    Given a string R that may be suffixed with a number, returns a
    tuple (ROLE, NUM) where ROLE+NUM == R and NUM is the maximal
    suffix of R consisting only of digits.
    """
    i = len(r)
    while i > 1 and r[i - 1].isdigit():
        i -= 1
    return r[:i], r[i:]


def multiply_elements(parameter_counts):
    """
    Compute the product of an iterable array with None as its element

    Parameters
    ----------
    array : iterable-of-numeric
        The numbers to use as input

    Returns
    -------
    number
        Product of all the elements of the array

    """
    result = 1
    for i in parameter_counts:
        if i is not None:
            result *= i
    return result


def normalize_diffs(diffs):
    """Normalize an array of eigenvalue diffs."""
    return diffs / diffs.mean()


def sorted_container_nodes(containers):
    """Returns a sorted iterable of containers sorted by label or id (whatever is available)

    Arguments:
        containers (iterable): The the list of containers to sort

    Returns:
        iterable: The sorted set of containers
    """
    return sorted(containers, key=lambda x: (x.label or x.id or '').lower(),
        reverse=True)


def deregister_patch_baseline_for_patch_group(BaselineId=None, PatchGroup=None
    ):
    """
    Removes a patch group from a patch baseline.
    See also: AWS API Documentation

    :example: response = client.deregister_patch_baseline_for_patch_group(
        BaselineId='string',
        PatchGroup='string'
    )

    :type BaselineId: string
    :param BaselineId: [REQUIRED]
            The ID of the patch baseline to deregister the patch group from.

    :type PatchGroup: string
    :param PatchGroup: [REQUIRED]
            The name of the patch group that should be deregistered from the patch baseline.

    :rtype: dict
    :return: {
        'BaselineId': 'string',
        'PatchGroup': 'string'
    }

    """
    pass


def reformat_version(version):
    """Hack to reformat old versions ending on '-alpha' to match pip format."""
    if version.endswith('-alpha'):
        return version.replace('-alpha', 'a0')
    return version.replace('-alpha', 'a')


def log(filename, message, verbose):
    """write message to log file and shell."""
    if verbose:
        print(message)
    if filename:
        output = open(filename, 'a')
        output.write(message + '\n')
        output.close()


@classmethod
def add_hostgroup(cls, options=None):
    """Adds a hostgroup to an org"""
    cls.command_sub = 'add-hostgroup'
    return cls.execute(cls._construct_command(options))


def advanceboundary(repo, tr, targetphase, nodes, dryrun=None):
    """Add nodes to a phase changing other nodes phases if necessary.

    This function move boundary *forward* this means that all nodes
    are set in the target phase or kept in a *lower* phase.

    Simplify boundary to contains phase roots only.

    If dryrun is True, no actions will be performed

    Returns a set of revs whose phase is changed or should be changed
    """
    phcache = repo._phasecache.copy()
    changes = phcache.advanceboundary(repo, tr, targetphase, nodes, dryrun=
        dryrun)
    if not dryrun:
        repo._phasecache.replace(phcache)
    return changes


def export_program(client, file_=None):
    """Export a model's program to a file.

    Args:
        client (obj):
            creopyson Client.
        `file_` (str, optional):
            Model name. Defaults is current active model.

    Returns:
        dict:
            dirname (str): Directory of the output file
            filename (str): Name of the output file

    """
    data = {}
    if file_ is not None:
        data['file'] = file_
    else:
        active_file = client.file_get_active()
        if active_file is not None:
            data['file'] = active_file['file']
    return client._creoson_post('interface', 'export_program', data)


def parse_config(config_list, filter_func=None):
    """Parses list with "name=value" strings.

    Args:
        config_list: A list of "name=value" strings
        filter_func: A function taking the parsing config name and value for each line.
            If the function returns True the config value will be included in the final
            dict.

    Returns: A dict containing parsed data.
    """
    result = dict()
    for line in config_list:
        try:
            name, value = line.split('=', 1)
        except ValueError:
            continue
        name = name.strip()
        value = value.strip()
        if filter_func is None or callable(filter_func) and filter_func(name,
            value):
            result[name] = value
    return result


def gather_nd(data=None, indices=None, out=None, name=None, **kwargs):
    """Gather elements or slices from `data` and store to a tensor whose
    shape is defined by `indices`.

    Given `data` with shape `(X_0, X_1, ..., X_{N-1})` and indices with shape
    `(M, Y_0, ..., Y_{K-1})`, the output will have shape `(Y_0, ..., Y_{K-1}, X_M, ..., X_{N-1})`,
    where `M <= N`. If `M == N`, output shape will simply be `(Y_0, ..., Y_{K-1})`.

    The elements in output is defined as follows::

      output[y_0, ..., y_{K-1}, x_M, ..., x_{N-1}] = data[indices[0, y_0, ..., y_{K-1}],
                                                          ...,
                                                          indices[M-1, y_0, ..., y_{K-1}],
                                                          x_M, ..., x_{N-1}]

    Examples::

      data = [[0, 1], [2, 3]]
      indices = [[1, 1, 0], [0, 1, 0]]
      gather_nd(data, indices) = [2, 3, 0]

      data = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
      indices = [[0, 1], [1, 0]]
      gather_nd(data, indices) = [[3, 4], [5, 6]]

    Parameters
    ----------
    data : NDArray
        data
    indices : NDArray
        indices

    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 build_href_tag(url, display_text, new_window=False, title=None):
    """
    Returns the HTML to build an <a href...> tag string from values supplied
    WARNING: There is NO filtering or escaping of ANY characters.
    Character cleansing must be performed prior to calling this method.
    """
    target = "target='_blank' " if new_window else ''
    return "<a {0}href='{1}'{2}>{3}</a>".format(target, url, 'title="{0}"'.
        format(title) if title else '', display_text)


def struc2sym(struc):
    """return a global symbol from a structure.

    In XMLRPC we cannot simply transfer references global objects.
    So can implement here a way to get a global object from an
    arbitrary structure. The default is to return the object
    itself.
    """
    return struc


def choose(cond, a, b):
    """(Deprecated) simulate `a if cond else b`."""
    if cond:
        return a
    return b


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 import_teamocil(sconf):
    """Return tmuxp config from a `teamocil`_ yaml config.

    .. _teamocil: https://github.com/remiprev/teamocil

    Parameters
    ----------
    sconf : dict
        python dict for session configuration

    Notes
    -----

    Todos:

    - change  'root' to a cd or start_directory
    - width in pane -> main-pain-width
    - with_env_var
    - clear
    - cmd_separator
    """
    tmuxp_config = {}
    if 'session' in sconf:
        sconf = sconf['session']
    if 'name' in sconf:
        tmuxp_config['session_name'] = sconf['name']
    else:
        tmuxp_config['session_name'] = None
    if 'root' in sconf:
        tmuxp_config['start_directory'] = sconf.pop('root')
    tmuxp_config['windows'] = []
    for w in sconf['windows']:
        windowdict = {'window_name': w['name']}
        if 'clear' in w:
            windowdict['clear'] = w['clear']
        if 'filters' in w:
            if 'before' in w['filters']:
                for b in w['filters']['before']:
                    windowdict['shell_command_before'] = w['filters']['before']
            if 'after' in w['filters']:
                for b in w['filters']['after']:
                    windowdict['shell_command_after'] = w['filters']['after']
        if 'root' in w:
            windowdict['start_directory'] = w.pop('root')
        if 'splits' in w:
            w['panes'] = w.pop('splits')
        if 'panes' in w:
            for p in w['panes']:
                if 'cmd' in p:
                    p['shell_command'] = p.pop('cmd')
                if 'width' in p:
                    p.pop('width')
            windowdict['panes'] = w['panes']
        if 'layout' in w:
            windowdict['layout'] = w['layout']
        tmuxp_config['windows'].append(windowdict)
    return tmuxp_config


def _get_download_base_url():
    """Returns base URL for data sets."""
    return 'http://scikit.ml/datasets/'


def kw2hp(power_kw):
    """Convert power from kW to HP"""
    return power_kw * 1.34102


def try_get_local_path(target):
    """ Try to get the local path for a tracked object """
    try:
        return target.local
    except AttributeError:
        return target


def as_tuple(*values):
    """
    Convert sequence of values in one big tuple.

    Parameters
    ----------
    *values
        Values that needs to be combined in one big tuple.

    Returns
    -------
    tuple
        All input values combined in one tuple

    Examples
    --------
    >>> as_tuple(None, (1, 2, 3), None)
    (None, 1, 2, 3, None)
    >>>
    >>> as_tuple((1, 2, 3), (4, 5, 6))
    (1, 2, 3, 4, 5, 6)
    """
    cleaned_values = []
    for value in values:
        if isinstance(value, (tuple, list)):
            cleaned_values.extend(value)
        else:
            cleaned_values.append(value)
    return tuple(cleaned_values)


@staticmethod
def p_btl_cycles(p):
    """btl_cycles : BTL_CYCLES NUMERIC"""
    p[0] = p[2]


@classmethod
def to_ordinal(cls, d):
    """Return week ordinal for date `d`."""
    return d.wk_ordinal


def p_expression_eq(p):
    """expression : expression EQ expression"""
    p[0] = p[1] == p[3]


def _has_newline(line):
    """Used by has_bad_header to check for \\r or \\n"""
    if line and ('\r' in line or '\n' in line):
        return True
    return False


def Mobility(Te, mu0, T0):
    """
    Temperature dependent mobility.

    See page 4 of Reference 1.

    35, 37, 38

    References
    ----------

    [1] Shiue et al. 2019
        URL: http://www.nature.com/articles/s41467-018-08047-3

    [2] Dorgan et al. 2013.
        URL: https://doi.org/10.1021/nl400197w

    [3] Bae et al. 2010
        URL: https://doi.org/10.1021/nl1011596
    """
    mu = mu0 * (Te / T0) ** 2.3
    return mu


def getLoopbackMode():
    """
        Return if loopback mode is enabled.
        """


@staticmethod
def _parse_tide_obs(in_str):
    """
        TODO: Add docstring

        """
    error_code_dict = {'M': 1, 'N': 2, 'T': 3}
    try:
        int(in_str[-1])
        error_code = 0
        meas = float(in_str)
    except:
        error_code_str = in_str[-1]
        meas = float(in_str[0:-1])
        try:
            error_code = error_code_dict[error_code_str]
        except:
            print('Unrecognised error code')
            return
    return meas, error_code


@classmethod
def FromJointStateAndTime(cls, joint_state, time):
    """initialize this trajectory point from a JointState object, and a specified time"""
    cls.FromJointState(joint_state)
    cls.t = time
    return cls


def resolve_key(obj, key):
    """Resolve key given an object and key."""
    if callable(key):
        return key(obj)
    elif hasattr(obj, 'metadata'):
        return obj.metadata[key]
    raise TypeError(
        'Could not resolve key %r. Key must be callable or %s must have `metadata` attribute.'
         % (key, obj.__class__.__name__))


def print_datum(datum=None, units='GiB'):
    """
    Print out the relevant fields from a bin containing aggregated values

    Args:
        datum (dict): the results of bin_datum
        units (str): units to print (KiB, MiB, GiB, TiB)
    """
    if datum is None:
        return '%28s %12s %12s %5s %5s %5s %5s %5s\n' % ('date/time',
            '%ss read' % units.lower(), '%ss writ' % units.lower(), 'ossav',
            'ossmx', 'mdsav', 'mdsmx', 'mssng')
    frac_missing = float(datum.get('missing_ost_read', 0) + datum.get(
        'missing_ost_write', 0)) / (datum.get('num_ost_read', 0) + datum.
        get('num_ost_write', 0))
    print_str = '%19s-%8s ' % (datum['tstart'].strftime('%Y-%m-%d %H:%M:%S'
        ), datum['tend'].strftime('%H:%M:%S'))
    print_str += '%%(sum_ost_read_%ss)12.2f ' % units.lower() % datum
    print_str += '%%(sum_ost_write_%ss)12.2f ' % units.lower() % datum
    if 'ave_oss_cpu' in datum:
        print_str += '%(ave_oss_cpu)5.1f ' % datum
    else:
        print_str += '%5s ' % ''
    if 'max_oss_cpu' in datum:
        print_str += '%(max_oss_cpu)5.1f ' % datum
    else:
        print_str += '%5s ' % ''
    if 'ave_mds_cpu' in datum:
        print_str += '%(ave_mds_cpu)5.1f ' % datum
    else:
        print_str += '%5s ' % ''
    if 'max_mds_cpu' in datum:
        print_str += '%(max_mds_cpu)5.1f' % datum
    else:
        print_str += '%5s' % ''
    print_str += '%6.1f' % (100.0 * frac_missing)
    return print_str + '\n'


@staticmethod
def _get_data_format_3(raw):
    """
        Validate that data is from RuuviTag and is Data Format 3

        Returns:
            string: Sensor data
        """
    try:
        if 'FF990403' not in raw:
            return None
        payload_start = raw.index('FF990403') + 6
        return raw[payload_start:]
    except:
        return None


@staticmethod
def _update_orbits(orbits, permutations):
    """
        Update orbits based on permutations. Orbits is modified in place.
        For every pair of items in permutations their respective orbits are
        merged.
        """
    for permutation in permutations:
        node, node2 = permutation
        first = second = None
        for idx, orbit in enumerate(orbits):
            if first is not None and second is not None:
                break
            if node in orbit:
                first = idx
            if node2 in orbit:
                second = idx
        if first != second:
            orbits[first].update(orbits[second])
            del orbits[second]


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


def _add_long_format_option(arg_parser, help_text):
    """
    Adds optional follow_symlinks parameter to a parser.
    :param arg_parser: ArgumentParser parser to add this argument to.
    """
    arg_parser.add_argument('-l', help=help_text, action='store_true', dest
        ='long_format')


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

        :param TeamFolderMetadata val:
        :rtype: TeamFolderArchiveJobStatus
        """
    return cls('complete', val)


def parse_element(tx, size):
    """ Parses a given transaction to extract an element of a given size.

    :param tx: Transaction where the element will be extracted.
    :type tx: TX
    :param size: Size of the parameter to be extracted.
    :type size: int
    :return: The extracted element.
    :rtype: hex str
    """
    element = tx.hex[tx.offset:tx.offset + size * 2]
    tx.offset += size * 2
    return element


def cleanupversion(ver):
    """massage the version number so it matches the format of install folder"""
    lst = ver.split('.')
    if len(lst) == 1:
        lst.extend(['0', '0'])
    elif len(lst) == 2:
        lst.extend(['0'])
    elif len(lst) > 2:
        lst = lst[:3]
    lst[2] = '0'
    cleanver = '.'.join(lst)
    return cleanver


def getTcpKeepAlive():
    """
        Return if C{SO_KEEPALIVE} is enabled.
        """


def find_next_newline(fp, filesize, startpos):
    """
    return the position of first newline found after given starting position
    """
    if startpos > filesize:
        return filesize
    if startpos <= 0:
        return 0
    fp.seek(startpos - 1)
    fp.readline()
    return fp.tell()


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 yieldroutes(func):
    """ Return a generator for routes that match the signature (name, args)
    of the func parameter. This may yield more than one route if the function
    takes optional keyword arguments. The output is best described by example::

        a()         -> '/a'
        b(x, y)     -> '/b/:x/:y'
        c(x, y=5)   -> '/c/:x' and '/c/:x/:y'
        d(x=5, y=6) -> '/d' and '/d/:x' and '/d/:x/:y'
    """
    import inspect
    path = '/' + func.__name__.replace('__', '/').lstrip('/')
    spec = inspect.getargspec(func)
    argc = len(spec[0]) - len(spec[3] or [])
    path += '/:%s' * argc % tuple(spec[0][:argc])
    yield path
    for arg in spec[0][argc:]:
        path += '/:%s' % arg
        yield path


def xml_search_helper(data, param):
    """Perform find or findall on given xml with string from param."""
    if isinstance(param, (tuple, list)) and param[1]:
        result = data.findall(param[0])
    else:
        result = data.find(param)
    return result


def helper_import(module_name, class_name=None):
    """
    Return class or module object.
    if the argument is only a module name and return a module object.
    if the argument is a module and class name, and return a class object.
    """
    module = __import__(module_name, globals(), locals(), [class_name])
    if not class_name:
        return module
    else:
        try:
            return getattr(module, class_name)
        except:
            return False


def rsqrt(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns element-wise inverse square-root value of the input.

    .. math::
       rsqrt(x) = 1/\\sqrt{x}

    Example::

       rsqrt([4,9,16]) = [0.5, 0.33333334, 0.25]

    The storage type of ``rsqrt`` output is always dense

    Defined in src/operator/tensor/elemwise_unary_op_pow.cc:L193

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

    name : string, optional.
        Name of the resulting symbol.

    Returns
    -------
    Symbol
        The result symbol.
    """
    return 0,


def _vars2list(params):
    """ Converts the variables on lists of the same length
    """
    length = 1
    for param in params:
        if isinstance(param, list):
            length = max(length, len(param))
    if length > 1:
        for param in params:
            if isinstance(param, list) and len(param) != length:
                raise Exception('Lists in parameters must the same length')
    result = []
    for param in params:
        if isinstance(param, list):
            result.append(param)
        else:
            result.append([param] * length)
    return result


@classmethod
def restore_padding(cls, token):
    """Restore padding based on token size.

        :param token: token to restore padding on
        :type token: six.text_type
        :returns: token with correct padding

        """
    mod_returned = len(token) % 4
    if mod_returned:
        missing_padding = 4 - mod_returned
        token += '=' * missing_padding
    return token


def format_percentage(n, precision='auto'):
    """Display a decimal number in percentage.

    Parameters
    =========
    n : float
        The number to format.
    percision: int, str, default 'auto'
        The precision of outcome. Default 'auto' to automatically
        choose the least precision on which the outcome is not zero.

    Examples
    ========
    format_percentage(0.001) ==> '0.1%'
    format_percentage(-0.0000010009) ==> '-0.0001%'
    format_percentage(0.001, 4) ==> '0.1000%'
    """
    if precision == 'auto':
        if n != 0:
            k = abs(n) * 100
            cnt = 0
            while k < 1:
                k = k * 10
                cnt += 1
            precision = cnt
        else:
            precision = 0
    fmt = '{:.' + str(precision) + '%}'
    return fmt.format(n)


@classmethod
def from_dict(cls, d):
    """Return a model instance from a dictionary."""
    return cls(**d)


def set_classes(options):
    """
    Auxiliary function to set options['classes'] and delete
    options['class'].
    """
    if 'class' in options:
        assert 'classes' not in options
        options['classes'] = options['class']
        del options['class']


def multihash(*args):
    """Multi-argument order-sensitive hash.

    Args:
        *args: Objects to hash.

    Returns:
        int: Hash.
    """
    return hash(args)


def get_merged_agp_coordinates(agp_iterable):
    """
    merges on an iterator on directly adjacent AGP entries and returns a new
    iterator with start and end coordinates inside a tuple
    assumes AGP entries have been converted to 0-based coordinates and assume
    AGP regions are sorted based on start coordinates
    """
    current_row = next(agp_iterable)
    for agp_row in agp_iterable:
        if current_row:
            if current_row['object_end'] >= agp_row['object_beg']:
                current_row['object_end'] = agp_row['object_end']
            else:
                yield current_row['object_beg'], current_row['object_end']
                current_row = agp_row
    if current_row:
        yield current_row['object_beg'], current_row['object_end']


def to_utf8(b: bytes) ->str:
    """Convert bytes to str utf-8 encoded."""
    return b.decode('utf-8')


@classmethod
def index(cls, value):
    """Return an index into the Enum given a value."""
    return cls.ALL.index(value)


def _solveTP(argdict):
    """
    Function that will be called by parallelizedTP with pool.map

    (must be defined on module level due to technical restrictions)

    :param argdict:
    :return:
    """
    from pytrajectory.system import TransitionProblem
    index, total = argdict.get('progress_info', (1, 1))
    print('Run {} / {}; \n with arguments: {}'.format(index, total, argdict))
    TP = TransitionProblem(**argdict)
    return TP.solve(return_format='info_container')


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

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

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


def attach_tz_if_none(dt, tz):
    """
    Makes a naive timezone aware or returns it if it is already aware.

    Attaches the timezone tz to the datetime dt if dt has no tzinfo. If
    dt already has tzinfo set, return dt.

    :type dt: datetime
    :param dt: A naive or aware datetime object.

    :type tz: pytz timezone
    :param tz: The timezone to add to the datetime

    :rtype: datetime
    :returns: An aware datetime dt with tzinfo set to tz. If dt already had
        tzinfo set, dt is returned unchanged.
    """
    return tz.localize(dt) if dt.tzinfo is None else dt


def enough_time(dates, day_delta):
    """Change detection requires a minimum amount of time (as specified by
    day_delta).

    This function, like `enough_samples` improves readability of logic
    that performs this check.

    Args:
        dates: list of ordinal day numbers relative to some epoch,
            the particular epoch does not matter.
        day_delta: minimum difference between time at meow_ix and most
            recent observation.

    Returns:
        bool: True if the represented time span is greater than day_delta
    """
    return dates[-1] - dates[0] >= day_delta


def speed_dst(distance, time):
    """Usage: speed_dst(distance traveled, time taken)"""
    return distance / time


def process(proc_data):
    """
    Final processing to conform to the schema.

    Parameters:

        proc_data:   (dictionary) raw structured data to process

    Returns:

        List of dictionaries. Structured data with the following schema:

        [
          {
            "chain":                string,
            "rules": [
              {
                "num"               integer,
                "pkts":             integer,
                "bytes":            integer,  # converted based on suffix
                "target":           string,
                "prot":             string,
                "opt":              string,   # "--" = Null
                "in":               string,
                "out":              string,
                "source":           string,
                "destination":      string,
                "options":          string
              }
            ]
          }
        ]
    """
    for entry in proc_data:
        for rule in entry['rules']:
            int_list = ['num', 'pkts']
            for key in int_list:
                if key in rule:
                    try:
                        key_int = int(rule[key])
                        rule[key] = key_int
                    except ValueError:
                        rule[key] = None
            if 'bytes' in rule:
                multiplier = 1
                if rule['bytes'][-1] == 'K':
                    multiplier = 1000
                    rule['bytes'] = rule['bytes'].rstrip('K')
                elif rule['bytes'][-1] == 'M':
                    multiplier = 1000000
                    rule['bytes'] = rule['bytes'].rstrip('M')
                elif rule['bytes'][-1] == 'G':
                    multiplier = 1000000000
                    rule['bytes'] = rule['bytes'].rstrip('G')
                elif rule['bytes'][-1] == 'T':
                    multiplier = 1000000000000
                    rule['bytes'] = rule['bytes'].rstrip('T')
                elif rule['bytes'][-1] == 'P':
                    multiplier = 1000000000000000
                    rule['bytes'] = rule['bytes'].rstrip('P')
                try:
                    bytes_int = int(rule['bytes'])
                    rule['bytes'] = bytes_int * multiplier
                except ValueError:
                    rule['bytes'] = None
            if 'opt' in rule:
                if rule['opt'] == '--':
                    rule['opt'] = None
    return proc_data


def get_bin_on_value_1d(val, arr):
    """Return index for value in one-dimensional array.

    *arr* must contain strictly increasing values
    (not necessarily equidistant),
    it is not checked.

    "Linear binary search" is used,
    that is our array search by default assumes
    the array to be split on equidistant steps.

    Example:

    >>> from lena.structures import get_bin_on_value_1d
    >>> arr = [0, 1, 4, 5, 7, 10]
    >>> get_bin_on_value_1d(0, arr)
    0
    >>> get_bin_on_value_1d(4.5, arr)
    2
    >>> # upper range is excluded
    >>> get_bin_on_value_1d(10, arr)
    5
    >>> # underflow
    >>> get_bin_on_value_1d(-10, arr)
    -1
    """
    ind_min = 0
    ind_max = len(arr) - 1
    while True:
        if ind_max - ind_min <= 1:
            if val < arr[ind_min]:
                return ind_min - 1
            elif val >= arr[ind_max]:
                return ind_max
            else:
                return ind_min
        if val == arr[ind_min]:
            return ind_min
        if val < arr[ind_min]:
            return ind_min - 1
        elif val >= arr[ind_max]:
            return ind_max
        else:
            shift = int((ind_max - ind_min) * (float(val - arr[ind_min]) /
                (arr[ind_max] - arr[ind_min])))
            ind_guess = ind_min + shift
            if ind_min == ind_guess:
                ind_min += 1
                continue
            elif ind_max == ind_guess:
                ind_max -= 1
                continue
            if val < arr[ind_guess]:
                ind_max = ind_guess
            else:
                ind_min = ind_guess


@staticmethod
def read_in_chunks(stream_object, chunk_size=1024):
    """Lazy function (generator) to read a file piece by piece.
        Default chunk size: 1k."""
    while True:
        data = stream_object.read(chunk_size)
        if not data:
            break
        yield data


def sign_ste(data=None, out=None, name=None, **kwargs):
    """Straight-through-estimator of `sign()`.

    In forward pass, returns element-wise sign of the input (same as `sign()`).

    In backward pass, returns gradients of ``1`` everywhere (instead of ``0`` everywhere as in ``sign()``):
    :math:`\\frac{d}{dx}{sign\\_ste(x)} = 1` vs. :math:`\\frac{d}{dx}{sign(x)} = 0`.
    This is useful for quantized training.

    Reference: Estimating or Propagating Gradients Through Stochastic Neurons for Conditional Computation.

    Example::
      x = sign_ste([-2, 0, 3])
      x.backward()
      x = [-1.,  0., 1.]
      x.grad() = [1.,  1., 1.]

    The storage type of ``sign_ste`` output depends upon the input storage type:
      - round_ste(default) = default
      - round_ste(row_sparse) = row_sparse
      - round_ste(csr) = csr

    Defined in src/operator/contrib/stes_op.cc:L80

    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 glColorMask(red, green, blue, alpha):
    """Enable and disable writing of frame buffer color components

    :param alpha: Specify whether red, green, blue, and alpha can or cannot be written into the frame buffer. The initial values are all GL_TRUE, indicating that the color components can be written.
    """
    pass


def _get_headers():
    """
    Craft HTTP headers for request
    """
    return {'Content-Type': 'application/x-www-form-urlencoded'}


def mediafile_data(mediafile):
    """Return json serializable data for the mediafile."""
    if mediafile is None:
        return None
    return {'url': mediafile.file.url, 'type': mediafile.type, 'created':
        mediafile.created, 'copyright': mediafile.copyright, 'file_size':
        mediafile.file_size}


def report_delete():
    """Delete selected reports

    """
    pass


def wordCount():
    """Return the number of unique terms in the lexicon."""


def _DOMTokenList_type(*args):
    """
        _DOMTokenList_type - A method which imports and returns SpecialAttributes.DOMTokenList

            for late-binding reasons

            If arguments are passed, will construct a DOMTokenList object, otherwise will return the type itself
    """
    from .SpecialAttributes import DOMTokenList
    if args:
        return DOMTokenList(*args)
    return DOMTokenList


def get_campaign_version(ApplicationId=None, CampaignId=None, Version=None):
    """
    Returns information about a specific version of a campaign.

    :example: response = client.get_campaign_version(
        ApplicationId='string',
        CampaignId='string',
        Version='string'
    )

    :type ApplicationId: string
    :param ApplicationId: [REQUIRED]

    :type CampaignId: string
    :param CampaignId: [REQUIRED]

    :type Version: string
    :param Version: [REQUIRED]

    :rtype: dict
    :return: {
        'CampaignResponse': {
            'AdditionalTreatments': [
                {
                    'Id': 'string',
                    'MessageConfiguration': {
                        'APNSMessage': {
                            'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                            'Body': 'string',
                            'ImageIconUrl': 'string',
                            'ImageUrl': 'string',
                            'JsonBody': 'string',
                            'MediaUrl': 'string',
                            'SilentPush': True|False,
                            'Title': 'string',
                            'Url': 'string'
                        },
                        'DefaultMessage': {
                            'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                            'Body': 'string',
                            'ImageIconUrl': 'string',
                            'ImageUrl': 'string',
                            'JsonBody': 'string',
                            'MediaUrl': 'string',
                            'SilentPush': True|False,
                            'Title': 'string',
                            'Url': 'string'
                        },
                        'GCMMessage': {
                            'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                            'Body': 'string',
                            'ImageIconUrl': 'string',
                            'ImageUrl': 'string',
                            'JsonBody': 'string',
                            'MediaUrl': 'string',
                            'SilentPush': True|False,
                            'Title': 'string',
                            'Url': 'string'
                        }
                    },
                    'Schedule': {
                        'EndTime': 'string',
                        'Frequency': 'ONCE'|'HOURLY'|'DAILY'|'WEEKLY'|'MONTHLY',
                        'IsLocalTime': True|False,
                        'QuietTime': {
                            'End': 'string',
                            'Start': 'string'
                        },
                        'StartTime': 'string',
                        'Timezone': 'string'
                    },
                    'SizePercent': 123,
                    'State': {
                        'CampaignStatus': 'SCHEDULED'|'EXECUTING'|'PENDING_NEXT_RUN'|'COMPLETED'|'PAUSED'
                    },
                    'TreatmentDescription': 'string',
                    'TreatmentName': 'string'
                },
            ],
            'ApplicationId': 'string',
            'CreationDate': 'string',
            'DefaultState': {
                'CampaignStatus': 'SCHEDULED'|'EXECUTING'|'PENDING_NEXT_RUN'|'COMPLETED'|'PAUSED'
            },
            'Description': 'string',
            'HoldoutPercent': 123,
            'Id': 'string',
            'IsPaused': True|False,
            'LastModifiedDate': 'string',
            'Limits': {
                'Daily': 123,
                'Total': 123
            },
            'MessageConfiguration': {
                'APNSMessage': {
                    'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                    'Body': 'string',
                    'ImageIconUrl': 'string',
                    'ImageUrl': 'string',
                    'JsonBody': 'string',
                    'MediaUrl': 'string',
                    'SilentPush': True|False,
                    'Title': 'string',
                    'Url': 'string'
                },
                'DefaultMessage': {
                    'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                    'Body': 'string',
                    'ImageIconUrl': 'string',
                    'ImageUrl': 'string',
                    'JsonBody': 'string',
                    'MediaUrl': 'string',
                    'SilentPush': True|False,
                    'Title': 'string',
                    'Url': 'string'
                },
                'GCMMessage': {
                    'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                    'Body': 'string',
                    'ImageIconUrl': 'string',
                    'ImageUrl': 'string',
                    'JsonBody': 'string',
                    'MediaUrl': 'string',
                    'SilentPush': True|False,
                    'Title': 'string',
                    'Url': 'string'
                }
            },
            'Name': 'string',
            'Schedule': {
                'EndTime': 'string',
                'Frequency': 'ONCE'|'HOURLY'|'DAILY'|'WEEKLY'|'MONTHLY',
                'IsLocalTime': True|False,
                'QuietTime': {
                    'End': 'string',
                    'Start': 'string'
                },
                'StartTime': 'string',
                'Timezone': 'string'
            },
            'SegmentId': 'string',
            'SegmentVersion': 123,
            'State': {
                'CampaignStatus': 'SCHEDULED'|'EXECUTING'|'PENDING_NEXT_RUN'|'COMPLETED'|'PAUSED'
            },
            'TreatmentDescription': 'string',
            'TreatmentName': 'string',
            'Version': 123
        }
    }

    :returns:
    (dict) -- 200 response
    CampaignResponse (dict) -- Campaign definition
    AdditionalTreatments (list) -- Treatments that are defined in addition to the default treatment.
    (dict) -- Treatment resource
    Id (string) -- The unique treatment ID.
    MessageConfiguration (dict) -- The message configuration settings.
    APNSMessage (dict) -- The message that the campaign delivers to APNS channels. Overrides the default message.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    DefaultMessage (dict) -- The default message for all channels.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    GCMMessage (dict) -- The message that the campaign delivers to GCM channels. Overrides the default message.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    Schedule (dict) -- The campaign schedule.
    EndTime (string) -- The scheduled time that the campaign ends in ISO 8601 format.
    Frequency (string) -- How often the campaign delivers messages. Valid values: ONCE, HOURLY, DAILY, WEEKLY, MONTHLY
    IsLocalTime (boolean) -- Indicates whether the campaign schedule takes effect according to each user's local time.
    QuietTime (dict) -- The time during which the campaign sends no messages.
    End (string) -- The default end time for quiet time in ISO 8601 format.
    Start (string) -- The default start time for quiet time in ISO 8601 format.

    StartTime (string) -- The scheduled time that the campaign begins in ISO 8601 format.
    Timezone (string) -- The starting UTC offset for the schedule if the value for isLocalTime is true Valid values: UTC UTC+01 UTC+02 UTC+03 UTC+03:30 UTC+04 UTC+04:30 UTC+05 UTC+05:30 UTC+05:45 UTC+06 UTC+06:30 UTC+07 UTC+08 UTC+09 UTC+09:30 UTC+10 UTC+10:30 UTC+11 UTC+12 UTC+13 UTC-02 UTC-03 UTC-04 UTC-05 UTC-06 UTC-07 UTC-08 UTC-09 UTC-10 UTC-11

    SizePercent (integer) -- The allocated percentage of users for this treatment.
    State (dict) -- The treatment status.
    CampaignStatus (string) -- The status of the campaign, or the status of a treatment that belongs to an A/B test campaign. Valid values: SCHEDULED, EXECUTING, PENDING_NEXT_RUN, COMPLETED, PAUSED

    TreatmentDescription (string) -- A custom description for the treatment.
    TreatmentName (string) -- The custom name of a variation of the campaign used for A/B testing.

    ApplicationId (string) -- The ID of the application to which the campaign applies.
    CreationDate (string) -- The date the campaign was created in ISO 8601 format.
    DefaultState (dict) -- The status of the campaign's default treatment. Only present for A/B test campaigns.
    CampaignStatus (string) -- The status of the campaign, or the status of a treatment that belongs to an A/B test campaign. Valid values: SCHEDULED, EXECUTING, PENDING_NEXT_RUN, COMPLETED, PAUSED

    Description (string) -- A description of the campaign.
    HoldoutPercent (integer) -- The allocated percentage of end users who will not receive messages from this campaign.
    Id (string) -- The unique campaign ID.
    IsPaused (boolean) -- Indicates whether the campaign is paused. A paused campaign does not send messages unless you resume it by setting IsPaused to false.
    LastModifiedDate (string) -- The date the campaign was last updated in ISO 8601 format.
    Limits (dict) -- The campaign limits settings.
    Daily (integer) -- The maximum number of messages that the campaign can send daily.
    Total (integer) -- The maximum total number of messages that the campaign can send.

    MessageConfiguration (dict) -- The message configuration settings.
    APNSMessage (dict) -- The message that the campaign delivers to APNS channels. Overrides the default message.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    DefaultMessage (dict) -- The default message for all channels.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    GCMMessage (dict) -- The message that the campaign delivers to GCM channels. Overrides the default message.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    Name (string) -- The custom name of the campaign.
    Schedule (dict) -- The campaign schedule.
    EndTime (string) -- The scheduled time that the campaign ends in ISO 8601 format.
    Frequency (string) -- How often the campaign delivers messages. Valid values: ONCE, HOURLY, DAILY, WEEKLY, MONTHLY
    IsLocalTime (boolean) -- Indicates whether the campaign schedule takes effect according to each user's local time.
    QuietTime (dict) -- The time during which the campaign sends no messages.
    End (string) -- The default end time for quiet time in ISO 8601 format.
    Start (string) -- The default start time for quiet time in ISO 8601 format.

    StartTime (string) -- The scheduled time that the campaign begins in ISO 8601 format.
    Timezone (string) -- The starting UTC offset for the schedule if the value for isLocalTime is true Valid values: UTC UTC+01 UTC+02 UTC+03 UTC+03:30 UTC+04 UTC+04:30 UTC+05 UTC+05:30 UTC+05:45 UTC+06 UTC+06:30 UTC+07 UTC+08 UTC+09 UTC+09:30 UTC+10 UTC+10:30 UTC+11 UTC+12 UTC+13 UTC-02 UTC-03 UTC-04 UTC-05 UTC-06 UTC-07 UTC-08 UTC-09 UTC-10 UTC-11

    SegmentId (string) -- The ID of the segment to which the campaign sends messages.
    SegmentVersion (integer) -- The version of the segment to which the campaign sends messages.
    State (dict) -- The campaign status. An A/B test campaign will have a status of COMPLETED only when all treatments have a status of COMPLETED.
    CampaignStatus (string) -- The status of the campaign, or the status of a treatment that belongs to an A/B test campaign. Valid values: SCHEDULED, EXECUTING, PENDING_NEXT_RUN, COMPLETED, PAUSED

    TreatmentDescription (string) -- A custom description for the treatment.
    TreatmentName (string) -- The custom name of a variation of the campaign used for A/B testing.
    Version (integer) -- The campaign version number.

    """
    pass


@staticmethod
def in_quart(progress):
    """.. image:: images/anim_in_quart.png
        """
    return progress * progress * progress * progress


def var_name_clean(line_in):
    """
    Removes #, $ and PVM_ from line_in, where line in is a string from a Bruker parameter list file.
    :param line_in: input string
    :return: output string cleaned from #, $ and PVM_
    """
    line_out = line_in.replace('#', '').replace('$', '').replace('PVM_', ''
        ).strip()
    return line_out


@staticmethod
def _more_options(remain):
    """Check if the remaining cli-arguments contain options."""
    return len(remain) > 0 and (remain[-1].startswith('--') or remain[-1].
        startswith('-'))


def avg2(num1, num2):
    """Returns the average of two numbers."""
    return (num1 + num2) / 2.0


def find_node(node_list_pyxb, base_url):
    """Search NodeList for Node that has {base_url}.

    Return matching Node or None

    """
    for node_pyxb in node_list_pyxb.node:
        if node_pyxb.baseURL == base_url:
            return node_pyxb


def decode_response(client_message, to_object=None):
    """ Decode response from client message"""
    parameters = dict(response=None)
    parameters['response'] = client_message.read_int()
    return parameters


@staticmethod
def _get_owner_cover_photo_upload_server(session, group_id, crop_x=0,
    crop_y=0, crop_x2=795, crop_y2=200):
    """
        https://vk.com/dev/photos.getOwnerCoverPhotoUploadServer
        """
    group_id = abs(group_id)
    response = session.fetch('photos.getOwnerCoverPhotoUploadServer',
        group_id=group_id, crop_x=crop_x, crop_y=crop_y, crop_x2=crop_x2,
        crop_y2=crop_y2)
    return response['upload_url']


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