@classmethod
def resolve_dependencies(cls, job_list, visit_list=None):
    """
        Solve the dependency graph expressed as a list of job definitions.

        :param list job_list: list of known jobs
        :param list visit_list: (optional) list of jobs to solve

        The visit_list, if specified, allows to consider only a part of the
        graph while still having access and knowledge of all jobs.

        :returns list: the solution (a list of jobs to execute in order)
        :raises DependencyDuplicateError:
            if a duplicate job definition is present
        :raises DependencyCycleError:
            if a cyclic dependency is present.
        :raises DependencyMissingErorr:
            if a required job does not exist.
        """
    return cls(job_list)._solve(visit_list)


def seconds_to_string(time_in_seconds):
    """Takes a time in seconds and returns a tuple of two strings "hh:mm:ss"
    and "ms"
    time in seconds -> ("hh:mm:ss", "ms")
    """
    milliseconds = time_in_seconds * 1000
    sec, milliseconds = divmod(round(milliseconds, 2), 1000)
    minutes, sec = divmod(round(time_in_seconds, 2), 60)
    hours, minutes = divmod(round(minutes, 2), 60)
    output = int(hours), int(minutes), int(sec), int(milliseconds)
    output = '{:02d}:{:02d}:{:02d}'.format(output[0], output[1], output[2]
        ), '{:03d}'.format(output[3])
    return output


def html_unquote(v):
    """
    Unquote (some) entities in HTML.  (incomplete)
    """
    for ent, repl in [(' ', ' '), ('>', '>'), ('<', '<'), (
        '"', '"'), ('&', '&')]:
        v = v.replace(ent, repl)
    return v


def find_initial_run(root):
    """ Scan all attempts in run to find lowest id """
    initial_run = None
    for item in root.findall('AttemptHistory/Attempt'):
        current_run = int(item.attrib['id'])
        if initial_run == None or current_run < initial_run:
            initial_run = current_run
    return initial_run


@classmethod
def get_from_name(cls, name):
    """Return the corresponding SIPMetadataType."""
    return cls.query.filter_by(name=name).one()


def _get_main_opset_version(model):
    """
    Returns the main opset version.
    """
    for op in model.opset_import:
        if op.domain == '':
            return op.version
    return None


def human_readable(size):
    """Transform size from bytes to human readable format (kB, MB, ...).

  :param size: Size in bytes.

  """
    for suffix in ['bytes', 'kB', 'MB', 'GB', 'TB']:
        if size < 1024.0:
            return '%3.1f%s' % (size, suffix)
        size /= 1024.0


def modify_cluster_subnet_group(ClusterSubnetGroupName=None, Description=
    None, SubnetIds=None):
    """
    Modifies a cluster subnet group to include the specified list of VPC subnets. The operation replaces the existing list of subnets with the new list of subnets.
    See also: AWS API Documentation

    :example: response = client.modify_cluster_subnet_group(
        ClusterSubnetGroupName='string',
        Description='string',
        SubnetIds=[
            'string',
        ]
    )

    :type ClusterSubnetGroupName: string
    :param ClusterSubnetGroupName: [REQUIRED]
            The name of the subnet group to be modified.

    :type Description: string
    :param Description: A text description of the subnet group to be modified.

    :type SubnetIds: list
    :param SubnetIds: [REQUIRED]
            An array of VPC subnet IDs. A maximum of 20 subnets can be modified in a single request.
            (string) --

    :rtype: dict
    :return: {
        'ClusterSubnetGroup': {
            'ClusterSubnetGroupName': 'string',
            'Description': 'string',
            'VpcId': 'string',
            'SubnetGroupStatus': 'string',
            'Subnets': [
                {
                    'SubnetIdentifier': 'string',
                    'SubnetAvailabilityZone': {
                        'Name': 'string'
                    },
                    'SubnetStatus': 'string'
                },
            ],
            'Tags': [
                {
                    'Key': 'string',
                    'Value': 'string'
                },
            ]
        }
    }

    """
    pass


def vertex_random(offset: float=0.1, uniform: float=0.0, normal: float=0.0,
    seed: int=0):
    """Randomize vertices

    :param offset: Amount, Distance to offset
    :type offset: float
    :param uniform: Uniform, Increase for uniform offset distance
    :type uniform: float
    :param normal: normal, Align offset direction to normals
    :type normal: float
    :param seed: Random Seed, Seed for the random number generator
    :type seed: int
    """
    pass


def merge_brle_lengths(lengths):
    """Inverse of split_long_brle_lengths."""
    if len(lengths) == 0:
        return []
    out = [int(lengths[0])]
    accumulating = False
    for length in lengths[1:]:
        if accumulating:
            out[-1] += length
            accumulating = False
        elif length == 0:
            accumulating = True
        else:
            out.append(int(length))
    return out


@classmethod
def _ap_find_potential_factories_in_module(cls, module):
    """
        Given a module that we're supposed to examine, iterate over
        the types that could be factories.

        This includes only types defined in that module. Any given
        type will only be returned once.
        """
    seen = set()
    for v in vars(module).values():
        if getattr(v, '__module__', None) != module.__name__ or not issubclass(
            type(v), type) or v in seen:
            continue
        seen.add(v)
        yield v


def adjustHF(H, F, n_new, n_old):
    """
    adjust hit/false alarm rate for ceiling effects
    according to Macmillan&Creelman, pp8
    urut/nov06
    """
    if H == 1:
        H = 1 - 1 / (2 * n_old)
    if F == 1:
        F = 1 - 1 / (2 * n_new)
    if H == 0:
        H = 1 / (2 * n_old)
    if F == 0:
        F = 1 / (2 * n_new)
    return H, F


def _set_ax_config(ax, str_x_axis, str_y_axis, size_labels=32, size_ticks=
    22, xlim_min=None, xlim_max=None, is_box=True, is_zero_axis=False,
    is_grid=True):
    """
    It sets an axis configuration.

    :param ax: inputs for acquisition function. Shape: (n, d).
    :type ax: matplotlib.axes._subplots.AxesSubplot
    :param str_x_axis: the name of x axis.
    :type str_x_axis: str.
    :param str_y_axis: the name of y axis.
    :type str_y_axis: str.
    :param size_labels: label size.
    :type size_labels: int., optional
    :param size_ticks: tick size.
    :type size_ticks: int., optional
    :param xlim_min: None, or minimum for x limit.
    :type xlim_min: NoneType or float, optional
    :param xlim_max: None, or maximum for x limit.
    :type xlim_max: NoneType or float, optional
    :param is_box: flag for drawing a box.
    :type is_box: bool., optional
    :param is_zero_axis: flag for drawing a zero axis.
    :type is_zero_axis: bool., optional
    :param is_grid: flag for drawing grids.
    :type is_grid: bool., optional

    :returns: None.
    :rtype: NoneType

    """
    if str_x_axis is not None:
        ax.set_xlabel(str_x_axis, fontsize=size_labels)
    ax.set_ylabel(str_y_axis, fontsize=size_labels)
    ax.tick_params(labelsize=size_ticks)
    if not is_box:
        ax.spines['top'].set_color('none')
        ax.spines['right'].set_color('none')
    if xlim_min is not None and xlim_max is not None:
        ax.set_xlim([xlim_min, xlim_max])
    if is_zero_axis:
        ax.spines['bottom'].set_position('zero')
    if is_grid:
        ax.grid()
    return


@classmethod
def get_scope(cls):
    """Get the required OAuth scope for this bot."""
    return set()


def vocab(table, text):
    """
    Return a new table containing only the vocabulary in the source text.

    Create a new translation table containing only the rules that are
    relevant for the given text. This is created by checking all source
    terms against a copy of the text.

    """
    text_rules = []
    text_copy = str(text)
    for rec in table:
        if rec[0] in text_copy:
            text_copy = text_copy.replace(rec[0], '\x1f')
            text_rules.append(rec)
    return text_rules


def metric(T_ant, T_sin, labels):
    """ Calcula el costo asociado al modelo

        cuenta la cantidad de antonimos en un mismo cluster
        y la cantidad de sinonimos fuera del cluster
    """
    n = len(T_ant)
    cost = 0
    for i in range(n):
        for j in range(i + 1, n):
            if T_ant[i, j] < 0.0:
                if labels[i] == labels[j]:
                    cost += 1
            if T_sin[i, j] > 0.0:
                if labels[i] != labels[j]:
                    cost += 1
    return cost


def pose_add(frame: int=1, name: str='Pose'):
    """Add the current Pose to the active Pose Library

    :param frame: Frame, Frame to store pose on
    :type frame: int
    :param name: Pose Name, Name of newly added Pose
    :type name: str
    """
    pass


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


def move_if_not_on_dow(original, replacement, dow_not_orig, dow_replacement):
    """
    Return a lambda function.

    Lambda checks that either the original day does not fall on a given
    weekday, or that the replacement day does fall on the expected weekday.
    """
    return lambda x: x.hdate.day == original and x.gdate.weekday(
        ) != dow_not_orig or x.hdate.day == replacement and x.gdate.weekday(
        ) == dow_replacement


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


def has_connected_children(bone):
    """ Returns true/false whether a bone has connected children or not.
    """
    t = False
    for b in bone.children:
        t = t or b.use_connect
    return t


def serialize_df(df, path, index=True):
    """Serializes a pandas DataFrame to a feather file on disk.

    If the data frame has a non-default index, that is added back as a column before writing out.

    Parameters
    ----------
    df : pandas.DataFrame
    path : str
        path to feather file to write
    index : bool
        if False, will drop the index
    """
    df = df.copy()
    if df.index.name or not index:
        df.reset_index(inplace=True, drop=not index or df.index.name in df.
            columns)
    df.to_feather(path)


def describe_job_flows(CreatedAfter=None, CreatedBefore=None, JobFlowIds=
    None, JobFlowStates=None):
    """
    This API is deprecated and will eventually be removed. We recommend you use  ListClusters ,  DescribeCluster ,  ListSteps ,  ListInstanceGroups and  ListBootstrapActions instead.
    DescribeJobFlows returns a list of job flows that match all of the supplied parameters. The parameters can include a list of job flow IDs, job flow states, and restrictions on job flow creation date and time.
    Regardless of supplied parameters, only job flows created within the last two months are returned.
    If no parameters are supplied, then job flows matching either of the following criteria are returned:
    Amazon EMR can return a maximum of 512 job flow descriptions.
    See also: AWS API Documentation

    :example: response = client.describe_job_flows(
        CreatedAfter=datetime(2015, 1, 1),
        CreatedBefore=datetime(2015, 1, 1),
        JobFlowIds=[
            'string',
        ],
        JobFlowStates=[
            'STARTING'|'BOOTSTRAPPING'|'RUNNING'|'WAITING'|'SHUTTING_DOWN'|'TERMINATED'|'COMPLETED'|'FAILED',
        ]
    )

    :type CreatedAfter: datetime
    :param CreatedAfter: Return only job flows created after this date and time.

    :type CreatedBefore: datetime
    :param CreatedBefore: Return only job flows created before this date and time.

    :type JobFlowIds: list
    :param JobFlowIds: Return only job flows whose job flow ID is contained in this list.
            (string) --

    :type JobFlowStates: list
    :param JobFlowStates: Return only job flows whose state is contained in this list.
            (string) --The type of instance.

    :rtype: dict
    :return: {
        'JobFlows': [
            {
                'JobFlowId': 'string',
                'Name': 'string',
                'LogUri': 'string',
                'AmiVersion': 'string',
                'ExecutionStatusDetail': {
                    'State': 'STARTING'|'BOOTSTRAPPING'|'RUNNING'|'WAITING'|'SHUTTING_DOWN'|'TERMINATED'|'COMPLETED'|'FAILED',
                    'CreationDateTime': datetime(2015, 1, 1),
                    'StartDateTime': datetime(2015, 1, 1),
                    'ReadyDateTime': datetime(2015, 1, 1),
                    'EndDateTime': datetime(2015, 1, 1),
                    'LastStateChangeReason': 'string'
                },
                'Instances': {
                    'MasterInstanceType': 'string',
                    'MasterPublicDnsName': 'string',
                    'MasterInstanceId': 'string',
                    'SlaveInstanceType': 'string',
                    'InstanceCount': 123,
                    'InstanceGroups': [
                        {
                            'InstanceGroupId': 'string',
                            'Name': 'string',
                            'Market': 'ON_DEMAND'|'SPOT',
                            'InstanceRole': 'MASTER'|'CORE'|'TASK',
                            'BidPrice': 'string',
                            'InstanceType': 'string',
                            'InstanceRequestCount': 123,
                            'InstanceRunningCount': 123,
                            'State': 'PROVISIONING'|'BOOTSTRAPPING'|'RUNNING'|'RESIZING'|'SUSPENDED'|'TERMINATING'|'TERMINATED'|'ARRESTED'|'SHUTTING_DOWN'|'ENDED',
                            'LastStateChangeReason': 'string',
                            'CreationDateTime': datetime(2015, 1, 1),
                            'StartDateTime': datetime(2015, 1, 1),
                            'ReadyDateTime': datetime(2015, 1, 1),
                            'EndDateTime': datetime(2015, 1, 1)
                        },
                    ],
                    'NormalizedInstanceHours': 123,
                    'Ec2KeyName': 'string',
                    'Ec2SubnetId': 'string',
                    'Placement': {
                        'AvailabilityZone': 'string',
                        'AvailabilityZones': [
                            'string',
                        ]
                    },
                    'KeepJobFlowAliveWhenNoSteps': True|False,
                    'TerminationProtected': True|False,
                    'HadoopVersion': 'string'
                },
                'Steps': [
                    {
                        'StepConfig': {
                            'Name': 'string',
                            'ActionOnFailure': 'TERMINATE_JOB_FLOW'|'TERMINATE_CLUSTER'|'CANCEL_AND_WAIT'|'CONTINUE',
                            'HadoopJarStep': {
                                'Properties': [
                                    {
                                        'Key': 'string',
                                        'Value': 'string'
                                    },
                                ],
                                'Jar': 'string',
                                'MainClass': 'string',
                                'Args': [
                                    'string',
                                ]
                            }
                        },
                        'ExecutionStatusDetail': {
                            'State': 'PENDING'|'RUNNING'|'CONTINUE'|'COMPLETED'|'CANCELLED'|'FAILED'|'INTERRUPTED',
                            'CreationDateTime': datetime(2015, 1, 1),
                            'StartDateTime': datetime(2015, 1, 1),
                            'EndDateTime': datetime(2015, 1, 1),
                            'LastStateChangeReason': 'string'
                        }
                    },
                ],
                'BootstrapActions': [
                    {
                        'BootstrapActionConfig': {
                            'Name': 'string',
                            'ScriptBootstrapAction': {
                                'Path': 'string',
                                'Args': [
                                    'string',
                                ]
                            }
                        }
                    },
                ],
                'SupportedProducts': [
                    'string',
                ],
                'VisibleToAllUsers': True|False,
                'JobFlowRole': 'string',
                'ServiceRole': 'string',
                'AutoScalingRole': 'string',
                'ScaleDownBehavior': 'TERMINATE_AT_INSTANCE_HOUR'|'TERMINATE_AT_TASK_COMPLETION'
            },
        ]
    }

    :returns:
    CreatedAfter (datetime) -- Return only job flows created after this date and time.
    CreatedBefore (datetime) -- Return only job flows created before this date and time.
    JobFlowIds (list) -- Return only job flows whose job flow ID is contained in this list.

    (string) --

    JobFlowStates (list) -- Return only job flows whose state is contained in this list.

    (string) --The type of instance.

    """
    pass


@classmethod
def get_point(cls, idx, size):
    """Get curve point coordinates by index.

        Parameters
        ----------
        idx : `int`
            Point index.
        size : `int`
            Curve size.

        Returns
        -------
        (`int`, `int`)
            Point coordinates.
        """
    x, y = cls.POSITION[idx % 4]
    idx //= 4
    block_size = 2
    while block_size < size:
        block_idx = idx % 4
        x, y = cls.get_point_in_block(x, y, block_idx, block_size)
        idx //= 4
        block_size *= 2
    return x, y


def _read_codon_usage_orgs_file(filename):
    """Reads Codon Usage Database table of species file."""
    codon_orgs = {}
    with open(filename, 'r') as textfile:
        next(textfile)
        for line in textfile:
            tokens = line.strip().split('\t')
            codon_orgs[tokens[0]] = tokens[1]
    return codon_orgs


def vslide(vel_1, vel_2):
    """

    Calculate the sliding speed in a tribological contact based on contact body
    velocities.

    Parameters
    ----------
    vel_1: ndarray, scalar
        The contact velocity of body 1.
    vel_2: ndarray, scalar
        The contact velocity of body 2

    Returns
    -------
    vel_slide: ndarray, scalar
        The sliding velocity in the tribological contact.

    """
    vel_slide = vel_1 - vel_2
    return vel_slide


def chunks(container, n):
    """
    Split a container into n-sized chunks.
    """
    for i in range(0, len(container), n):
        yield container[i:i + n]


def help(update, context):
    """Send a message when the command /help is issued."""
    update.message.reply_text(
        """Send:
/plot start end i,j,k...
to get a plot of cultures No. i, j, k...
"""
         +
        """from the time moment start  till the end.
Example:
/plot 5h 1w 0,1,2,3,4,5,6
"""
         +
        'plots the OD in 0th, 1st, ..., 6th tubes from t=5h to t = 1week \n\n'
         +
        """/pumpdata for pump_data.csv
/rawsignal for raw_signal.csv

""" +
        '/getvolumes to get death volumes\n' +
        '/getthresholds to get thresholds\n' + '/lastdata\n' +
        """/setvolumes 0,1,2,3,4,5,6 to change volumes. Only for the registered IDs!
"""
         +
        '/setthresholds 0,1,2,3,4,5,6 to change thresholds. Only for the registered IDs!\n'
         + """/plotOD
 /convertODs
/setconditions tube,vol,ODraw""")


def dump_defaults(roles):
    """Return a dict of all passed roles defaults"""
    defaults_dict = {}
    for role in roles:
        if role['defaults']:
            defaults_dict.update(role['defaults'])
    return defaults_dict


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

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

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

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

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

    """
    pass


@staticmethod
def postprocess(target):
    """ Run the code after generation.

        :return target:

        """
    return target


@classmethod
def configurable_default(cls):
    """Returns the implementation class to be used if none is configured."""
    raise NotImplementedError()


def _sqlite_cast_as_real(value):
    """Convert value to REAL (float) or default to 0.0 to match SQLite
    behavior. See the "Conversion Processing" table in the "CAST
    expressions" section for details:

        https://www.sqlite.org/lang_expr.html#castexpr
    """
    try:
        return float(value)
    except ValueError:
        return 0.0


def key_from_req(req):
    """Get an all-lowercase version of the requirement's name."""
    if hasattr(req, 'key'):
        return req.key
    else:
        return req.name.lower()


def clamp(value, min_value, max_value):
    """Clamps a value witin the bound [min_value, max_value]

    Returns
    -------
    float
    """
    if min_value > max_value:
        raise ValueError('min_value must be bigger than max_value')
    return float(min(max(value, min_value), max_value))


def FitCBVs(model):
    """
  Fits the CBV design matrix to the de-trended flux of a given target. This
  is called internally whenever the user accesses the :py:attr:`fcor`
  attribute.

  :param model: An instance of the :py:obj:`everest` model for the target

  """
    raise NotImplementedError('This mission is not yet supported.')


@staticmethod
def palette(x):
    """
        Aesthetic mapping function
        """
    raise NotImplementedError('Not Implemented')


@classmethod
def parse(cls, string):
    """ Parse a string into python objects """
    raise NotImplementedError


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

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

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


@staticmethod
def _call_with_frames_removed(f, *args, **kwds):
    """remove_importlib_frames in import.c will always remove sequences
        of importlib frames that end with a call to this function

        Use it instead of a normal call in places where including the importlib
        frames introduces unwanted noise into the traceback (e.g. when executing
        module code)
        """
    return f(*args, **kwds)


@classmethod
def Yaxis(cls):
    """Construct a unit vector along the Y axis.

        Returns
        -------
        :class:`compas.geometry.Vector`
            A vector with components ``x = 0.0, y = 1.0, z = 0.0``.

        Examples
        --------
        >>> Vector.Yaxis()
        Vector(0.000, 1.000, 0.000)
        """
    return cls(0.0, 1.0, 0.0)


@classmethod
def hydrate_raw(cls, query, bindings=None, connection=None):
    """
        Create a collection of models from a raw query.

        :param query: The SQL query
        :type query: str

        :param bindings: The query bindings
        :type bindings: list

        :param connection: The connection name

        :rtype: Collection
        """
    instance = cls().set_connection(connection)
    items = instance.get_connection().select(query, bindings)
    return cls.hydrate(items, connection)


def sma(data, col, w):
    """
    This function simply returns simple moving average of the timeseries at desired window

    Parameters:
    data: raw data
    col: column name of timeseries
    w: desired window

    Output:
    Returns initial dataframe with simple moving average column added to the end
    """
    data[str(w) + 'M SMA'] = data[col].rolling(window=w).mean()
    return data


def __add__(other):
    """A DateTime may be added to a number and a number may be
        added to a DateTime; two DateTimes cannot be added."""


@classmethod
def from_dict(cls, params):
    """
        Return an instance constructed using the given dict of params. This
        method is deliberately less flexible than the class `__init__()` method
        and requires all of the `__init__()` args to be given in the dict of
        params.

        :param params: a dict of parameters
        :return: an instance of this class
        """
    return cls(params['name'], params['timestamp'], params['lower'], params
        ['upper'], params['object_count'], params['bytes_used'], params[
        'meta_timestamp'], params['deleted'], params['state'], params[
        'state_timestamp'], params['epoch'])


def move_address_to_vpc(DryRun=None, PublicIp=None):
    """
    Moves an Elastic IP address from the EC2-Classic platform to the EC2-VPC platform. The Elastic IP address must be allocated to your account for more than 24 hours, and it must not be associated with an instance. After the Elastic IP address is moved, it is no longer available for use in the EC2-Classic platform, unless you move it back using the  RestoreAddressToClassic request. You cannot move an Elastic IP address that was originally allocated for use in the EC2-VPC platform to the EC2-Classic platform.
    See also: AWS API Documentation

    Examples
    This example moves the specified Elastic IP address to the EC2-VPC platform.
    Expected Output:

    :example: response = client.move_address_to_vpc(
        DryRun=True|False,
        PublicIp='string'
    )

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

    :type PublicIp: string
    :param PublicIp: [REQUIRED]
            The Elastic IP address.

    :rtype: dict
    :return: {
        'AllocationId': 'string',
        'Status': 'MoveInProgress'|'InVpc'|'InClassic'
    }

    """
    pass


@classmethod
def prepare_field(cls, field: 'ModelField') ->None:
    """
        Optional hook to check or modify fields during model creation.
        """
    pass


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

    :return: rst string
    :rtype: str
    """
    return """
    The ``logcheckresult`` model is used to maintain a log of the received checks results.

    The Alignak backend stores all the checks results it receives to keep a full log of the system
    checks results.
    """


@classmethod
def from_stream(cls, stream, marker_code, offset):
    """
        Extract the horizontal and vertical dots-per-inch value from the APP1
        header at *offset* in *stream*.
        """
    segment_length = stream.read_short(offset)
    if cls._is_non_Exif_APP1_segment(stream, offset):
        return cls(marker_code, offset, segment_length, 72, 72)
    tiff = cls._tiff_from_exif_segment(stream, offset, segment_length)
    return cls(marker_code, offset, segment_length, tiff.horz_dpi, tiff.
        vert_dpi)


def rename_dict(d, ids=None):
    """Assigns new key names to a dictionary.

    Parameters
    ----------
    d : dict
        Dictionary to rename.
    ids : optional, array_like(shape=(len(d)))
        Desired key names. If none, the keys are numbered consecutively.

    Returns
    -------
    dict
        Dictionary with new names.

    Examples
    --------

    >>> d = {1: [0, 1], 2: None, 3: 'text'}
    >>> renamed_dict = rename_dict(d, ['first', 'second', 'last'])
    >>> print(sorted(renamed_dict))
    ['first', 'last', 'second']

    """
    if not isinstance(d, dict):
        raise TypeError('dictionary required')
    if ids is None:
        ids = range(len(d))
    elif not len(ids) == len(d):
        raise ValueError('same number of keys required')
    return dict(zip(ids, d.values()))


def dir_name(fp, **kwargs):
    """
    Return the name of the directory where the file is located
    """
    return fp.rpartition('/')[0].rpartition('/')[2]


def argmin(l):
    """
    Return the position of the minimal element in the list ``l``.

    EXAMPLES::

        sage: from surface_dynamics.misc.permutation import argmin
        sage: argmin([3,0,1,2])
        1
        sage: argmin([-1,3,5,-2,50])
        3
    """
    if not l:
        raise ValueError('empty list')
    imin = 0
    jmin = l[0]
    for i, j in enumerate(l):
        if j < jmin:
            jmin = j
            imin = i
    return imin


def round_down(n):
    """"Rounds number n to nearest 100th place

    Parameters
    ----------
    n: int/float, a number to round down

    Returns
    -------
    n: float, n rounded to nearest 100th place
    """
    return float(int(n / 100) * 100)


@staticmethod
def __normalize_int(value, default=0):
    """
        Normalizes an integer value
        """
    try:
        return int(value)
    except (ValueError, TypeError):
        return default


@classmethod
def equal_to_constraint(cls, variables, value):
    """Clauses encoding a "equal to" constraint

        E.g. X1 + X2 + X3 + X4 = 1

        (X1 v X2 v X3 v X4)
        (~X1 v ~X2)
        (~X1 v ~X3)
        (~X1 v ~X4)
        (~X2 v ~X3)
        (~X2 v ~X4)
        (~X3 v ~X4)

        Parameters
        ----------
        variables : list of variables
           variables in the constraint
        value: int
           target values

        Returns
        -------
            a list of clauses
        """
    for c in cls.less_or_equal_constraint(variables, value):
        yield c
    for c in cls.greater_or_equal_constraint(variables, value):
        yield c


def theta_H_K_PK74(T, P):
    """c-c': hydrogen potassium [PK74]."""
    theta = 0.005
    valid = T == 298.15
    return theta, valid


def lerp(start, end, alpha):
    """
    Computes a linear interpolation between two values
    :param start: start value to interpolate from
    :param end:  end value to interpolate to
    :param alpha: how far we want to interpolate (0=start, 1=end)
    :return: float, result of the linear interpolation
    """
    return start + alpha * (end - start)


@staticmethod
def _wrap_encode_items(items):
    """Return `items` encoded as bytes.

        Parameters
        ----------
        items : list of PDU items
            The items to encode.

        Returns
        -------
        bytes
            The encoded items.
        """
    bytestream = bytes()
    for item in items:
        bytestream += item.encode()
    return bytestream


def filters(inst):
    """Function to show availalbe filters

  Parameters
  ----------
  inst : str
    string of either niriss, nirspec, miri or nircam

  Returns
  -------
  list
    list with availalbe filters
  """
    print(
        "Filters field stored in inst_dict['configuration']['instrument']['filter']"
        )
    if inst.lower() == 'niriss':
        print('No filters for niriss soss, type None, or null in filter field')
        return [None]
    elif inst.lower() == 'nirspec':
        return ['f070lp', 'f100lp', 'f170lp', 'f290lp', 'clear']
    elif inst.lower() == 'miri':
        print('No filters for miri lrs, type None, or null in filter field')
        return [None]
    elif inst.lower() == 'nircam':
        return ['f322w2', 'f444w']
    else:
        raise Exception(
            'Only instruments are niriss, nirspec, miri, nircam. Pick one.')


def neighbors(G, n, t=None):
    """Return a list of the nodes connected to the node n at time t.

            Parameters
            ----------

            G : Graph opject
                DyNetx graph object

            n : node
               A node in the graph

            t : snapshot id (default=None)
                If None will be returned the neighbors of the node on the flattened graph.

            Returns
            -------
            nlist : list
                A list of nodes that are adjacent to n.

            Raises
            ------
            NetworkXError
                If the node n is not in the graph.

            Examples
            --------
            >>> G = dn.DynGraph()
            >>> G.add_path([0,1,2,3], t=0)
            >>> dn.neighbors(G, 0, t=0)
            [1]
            >>> dn.neighbors(G, 0, t=1)
            []
            """
    return G.neighbors(n, t)


def _build_stream_body_map(attachments):
    """
    build stream body map
    :param attachments:
    :return:
    """
    multipart_files = {}
    if isinstance(attachments, dict):
        for i in attachments.keys():
            multipart_files['attachments[%s][]' % i] = attachments[i]
    return multipart_files


def default(value):
    """
    Given a python object, return the default value
    of that object.

    :param value: The value to get the default of
    :returns: The default value
    """
    return type(value)()


@classmethod
def _get_origin(cls):
    """Return list of Model names for origin Reference"""
    return ['account.invoice.line']


def get_model(instance):
    """Returns the model object from instance"""
    return instance._meta.model


def create_directory(Name=None, SchemaArn=None):
    """
    Creates a  Directory by copying the published schema into the directory. A directory cannot be created without a schema.
    See also: AWS API Documentation

    :example: response = client.create_directory(
        Name='string',
        SchemaArn='string'
    )

    :type Name: string
    :param Name: [REQUIRED]
            The name of the Directory . Should be unique per account, per region.

    :type SchemaArn: string
    :param SchemaArn: [REQUIRED]
            The Amazon Resource Name (ARN) of the published schema that will be copied into the data Directory . For more information, see arns .

    :rtype: dict
    :return: {
        'DirectoryArn': 'string',
        'Name': 'string',
        'ObjectIdentifier': 'string',
        'AppliedSchemaArn': 'string'
    }

    """
    pass


@classmethod
def factory(cls, global_config, **local_config):
    """Used for paste app factories in paste.deploy config files.

        Any local configuration (that is, values under the [app:APPNAME]
        section of the paste config) will be passed into the `__init__` method
        as kwargs.

        A hypothetical configuration would look like:

            [app:wadl]
            latest_version = 1.3
            paste.app_factory = nova.api.fancy_api:Wadl.factory

        which would result in a call to the `Wadl` class as

            import tacker.api.fancy_api
            fancy_api.Wadl(latest_version='1.3')

        You could of course re-implement the `factory` method in subclasses,
        but using the kwarg passing it shouldn't be necessary.

        """
    return cls(**local_config)


def store(folder, debug=False):
    """Stores data in the kitti format."""
    raise NotImplementedError


def _get_tmpdir_fixture_name(scope: str) ->str:
    """Get appropriately-scoped tmpdir fixture."""
    if scope == 'session':
        return 'session_tmpdir_path'
    else:
        return 'tmpdir_path'


def read_file(path):
    """Read contents from a local file."""
    with open(path, 'r') as file:
        return file.read()


@classmethod
def create(cls):
    """
        Return always the same instance of the backend class
        """
    if cls not in cls._instances:
        cls._instances[cls] = cls()
    return cls._instances[cls]


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 get_op_symbol(obj, fmt='%s', symbol_data=symbol_data, type=type):
    """Given an AST node object, returns a string containing the symbol.
    """
    return fmt % symbol_data[type(obj)]


def next_index(l, i):
    """
    Returns the index "i" of the next point in the list "l."  Work around
    for reaching the end to go to the start.
    """
    if i == len(l) - 1:
        i = 0
    else:
        i += 1
    return i


@classmethod
def for_keys_to_dict(cls, *args: tuple, my_dict: dict) ->dict:
    """
        指定多个key，并获取一个字典的多个对应的key，组成一个新的字典

        :Arg:
         - args: 指定的key值, TUPLE TYPE.
         - my_dict: 解析的字典, DICT TYPE.

        :Usage:
            for_keys_to_do_dict('hello', {'hello': 'hello'})
        """
    result = {}
    if len(args) > 0:
        for key in args:
            result.update({key: cls.get_value(my_dict, str(key))})
    return result


def get_ledger_coa(ledger_model):
    """
    Utility function to get the associated ledger's Chart of Account model.
    :param ledger_model: A Ledger model instance
    :return:
    """
    return ledger_model.entity.coa


@classmethod
def get_saved_info_schema(cls, resource_type):
    """Returns the saved info schema for a resource type

        :returns: a dictionary representing the schema
        """
    raise NotImplementedError


def code(Tuple):
    """
    Turns book,chapter,verse tuple into searchable string.
    Returns a searchable string.
    """
    book = str(Tuple[0])
    chapter = str(Tuple[1])
    verse = str(Tuple[2])
    book = book.zfill(2)
    chapter = chapter.zfill(3)
    verse = verse.zfill(3)
    return book + ':' + chapter + ':' + verse


def to_id(series):
    """Convert a series to an ID type."""
    return series


def GetWSAActionOutput(operation):
    """Find wsa:Action attribute, and return value or the default."""
    attr = operation.output.action
    if attr is not None:
        return attr
    targetNamespace = operation.getPortType().getTargetNamespace()
    ptName = operation.getPortType().name
    msgName = operation.output.name
    if not msgName:
        msgName = operation.name + 'Response'
    if targetNamespace.endswith('/'):
        return '%s%s/%s' % (targetNamespace, ptName, msgName)
    return '%s/%s/%s' % (targetNamespace, ptName, msgName)


def is_empty(value):
    """(Logic) is None, NaN, empty or blank str"""
    return (value is None or value == 'NaN' or value == 'NaT' or value ==
        'None' or value == '' or value in '                        ' or
        value == '(null)')


def p_enum_item(p):
    """enum_item : IDENTIFIER '=' INTCONSTANT
                 | IDENTIFIER"""
    if len(p) == 4:
        p[0] = [p[1], p[3]]
    elif len(p) == 2:
        p[0] = [p[1], None]


@classmethod
def from_geojson(cls, geojson):
    """
        Construct a Workflows FeatureCollection from a GeoJSON mapping.

        Note that the GeoJSON must be relatively small (under 10MiB of serialized JSON).

        Parameters
        ----------
        geojson: Dict

        Returns
        -------
        ~descarteslabs.workflows.FeatureCollection
        """
    try:
        if geojson['type'].lower() != 'featurecollection':
            raise ValueError(
                'Expected a GeoJSON FeatureCollection type, not {!r}'.
                format(geojson['type']))
        return cls._from_apply(cls._constructor, geojson['features'])
    except KeyError:
        raise ValueError(
            "Expected a GeoJSON mapping containing the field 'type' and 'features', but got {}"
            .format(geojson))


@classmethod
def open(cls, *args, **kwargs):
    """ Alias for FileIO() """
    return cls(*args, **kwargs)


@staticmethod
def _decode_bool(_packet):
    """Decode a boolean option value"""
    return True


def GetMerkleRoot(header):
    """

    gets the merkle root of the transactions contained in the block

    """
    pass


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

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

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


def cache_del(key, cache=None):
    """Deletes the given cached key from the cache.

    :param str|unicode key: The cache key to delete.

    :param str|unicode cache: Cache name with optional address (if @-syntax is used).

    :rtype: None
    """
    return False


def qn(namespace, tag_name):
    """Return the qualified name for a given namespace and tag name

    This is the ElementTree representation of a qualified name
    """
    return '{%s}%s' % (namespace, tag_name)


@classmethod
def allocate(cls, context, builder, list_type, nitems):
    """
        Allocate a ListInstance with its storage.  Same as allocate_ex(),
        but return an initialized *instance*.  If allocation failed,
        control is transferred to the caller using the target's current
        call convention.
        """
    ok, self = cls.allocate_ex(context, builder, list_type, nitems)
    with builder.if_then(builder.not_(ok), likely=False):
        context.call_conv.return_user_exc(builder, MemoryError, (
            'cannot allocate list',))
    return self


def import_no_db_in_virt(logical_line, filename):
    """Check for db calls from nova/virt

    As of grizzly-2 all the database calls have been removed from
    nova/virt, and we want to keep it that way.

    N307
    """
    if 'nova/virt' in filename and not filename.endswith('fake.py'):
        if logical_line.startswith('from nova.db import api'):
            yield 0, 'N307: nova.db.api import not allowed in nova/virt/*'


def select_less():
    """Deselect keyframes on ends of selection islands

    """
    pass


@staticmethod
def _map_preds(pred):
    """Before writing to disk"""
    if pred == 0:
        res = 'w'
    elif pred == 1:
        res = 'n'
    elif pred == 2:
        res = 'r'
    else:
        res = pred.cpu().numpy() - 2
    return str(res)


def cast(typ, val):
    """Cast a value to a type.

    This returns the value unchanged.  To the type checker this
    signals that the return value has the designated type, but at
    runtime we intentionally don't check anything (we want this
    to be as fast as possible).
    """
    return val


def _accumulate(iterable, fn=lambda x, y: x + y):
    """Taken from PyTorch"""
    it = iter(iterable)
    try:
        total = next(it)
    except StopIteration:
        return
    yield total
    for element in it:
        total = fn(total, element)
        yield total


@classmethod
def create(cls, **kwargs):
    """Create and persist a new record for the model
        :param kwargs: attributes for the record
        :return: the new model instance
        """
    return cls().fill(**kwargs).save()


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


def get_main_cnpj(store):
    """Get the MAIN_COMPANY' cnpj without ORM interaction"""
    result = store.execute(
        """
        SELECT company.cnpj
        FROM parameter_data, branch, company
        WHERE field_name = 'MAIN_COMPANY' AND
              branch.id::text = field_value AND
              branch.person_id = company.person_id;"""
        )
    data = result.get_one()
    result.close()
    return data[0] if data else ''


def contrast_ratio(l1, l2):
    """Given two relative luminances, calculate their contrast ratio."""
    return (l1 + 0.05) / (l2 + 0.05)


def _metadata(image, datapath):
    """Function which returns metadata dict.

    :param image: image to get spacing from
    :param datapath: path to data
    :return: {'series_number': '', 'datadir': '', 'voxelsize_mm': ''}
    """
    metadata = {'series_number': 0, 'datadir': datapath}
    spacing = image.GetSpacing()
    metadata['voxelsize_mm'] = [spacing[2], spacing[0], spacing[1]]
    return metadata


@classmethod
def create(cls, req):
    """create a new user, using data from req"""
    self = cls.new()
    self.store(req)
    return self


def unescapeDoubleDash(args):
    """Unescape all escaped '--' strings in the array."""
    return map(lambda x: x.replace('\\--', '--'), args)


def prepareArguments(arguments):
    """Prepares arguments for the command line"""
    args = []
    for index, _ in enumerate(arguments):
        args.append('${CDM_ARG' + str(index) + '}')
    return args


def slash_url_suffix(url, suffix):
    """Adds a slash either to the beginning or the end of a suffix
    (which is to be appended to a URL), depending on whether or not
    the URL ends with a slash."""
    return url.endswith('/') and '%s/' % suffix or '/%s' % suffix


def normalize_string(value):
    """Some parameterized tests encode the parameter objects into the test case name. For classes that have a
    proper output operator << implemented this is not an issue but classes without one produce a large test
    case with some byte object representation.

    Some examples how such test case names look like:

    .. code-block:: none

        ShapePointsTest/0 (lat = 51.8983, lon = 19.5026)
        GatewayTwinLinksQuantityTest/0 (16-byte object <60-A5 DE-03 00-00 00-00 02-00 02-00 00-00 00-00>)
        TestPassageRestrictions/0 (TestData: testPoint(44.6553, 7.38968)   Handle:               0

    We do not allow this and clean this up by removing everything after ` (`) and store only the real test case
    name and the index of the parameterized test.

    Args:
        value: String to be normalized
    """
    if value is None:
        return ''
    head, _, _ = value.partition(' (')
    return head.strip()


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 _auth_type_from_header(header):
    """
    Given a WWW-Authenticate or Proxy-Authenticate header, returns the
    authentication type to use. We prefer NTLM over Negotiate if the server
    suppports it.
    """
    if 'ntlm' in header:
        return 'NTLM'
    elif 'negotiate' in header:
        return 'Negotiate'
    return None


def decoder(method):
    """
    Mark a method as decoder when it is hooked.
    """
    method.__carly__decoder__ = True
    return method


def _create_mapping(grammar):
    """
    Create mapping between symbols and rules rewritable to these symbols.
    :param grammar: Grammar to use.
    :return: Tuple of two dictionaries.
    First dictionary maps rule to terminal hash.
    Second dictionary maps rule to nonterminals hash.
    """
    termmap = dict()
    rulemap = dict()
    for r in grammar.rules:
        if len(r.right) == 1:
            h = hash(r.toSymbol)
            if h not in termmap:
                termmap[h] = set()
            termmap[h].add(r)
        else:
            key = hash(tuple(r.right))
            if key not in rulemap:
                rulemap[key] = set()
            rulemap[key].add(r)
    return termmap, rulemap


def reply(zelf, *args, **kwargs):
    """ send reply to origin. """
    if 'outer' in zelf:
        zelf.outer.write(str(args[0]) + '\n')
        zelf.outer.flush()
        return
    if 'channel' in zelf:
        zelf.say(zelf.channel, args[0])
    else:
        zelf.say(zelf.origin, args[0])


def _get_shard_index(job_name, task_id):
    """ Returns the current shard index """
    if job_name != 'worker':
        return None
    return task_id


def iter_slices(string, slice_length):
    """Iterate over slices of a string."""
    pos = 0
    while pos < len(string):
        yield string[pos:pos + slice_length]
        pos += slice_length


def addargs(parser):
    """ Parse command line arguments for s4cmb """
    parser.add_argument('-inifile', dest='inifile', required=True, help=
        'Configuration file with parameter values.')
    parser.add_argument('-tag', dest='tag', required=True, help=
        'Tag name to identify your run. E.g. run_0_crosstalk.')
    parser.add_argument('-inifile_xpure', dest='inifile_xpure', default=
        None, help='Configuration file with xpure parameter values.')
    parser.add_argument('-type_hwp', dest='type_hwp', default=None, help=
        'The type of HWP that you want to mount on your instrument.')
    parser.add_argument('-freq_hwp', dest='freq_hwp', default=None, type=
        float, help='The frequency of rotation of the HWP in Hz.')
    parser.add_argument('-angle_hwp', dest='angle_hwp', default=None, type=
        float, help='The offset of the HWP in degree.')
    parser.add_argument('-input_filename', dest='input_filename', required=
        True, nargs='+', help='Input fits with alms.')
    parser.add_argument('-array_noise_seed', dest='array_noise_seed',
        required=True, type=int, help='Seed to generate noise.')
    parser.add_argument('-sim_number', dest='sim_number', required=True,
        type=int, help='Number of the sim.')
    parser.add_argument('-folder_out', dest='folder_out', required=True,
        help='Name of the output folder.')
    parser.add_argument('-nside_in', dest='nside_in', required=True, type=
        int, help='Name of the output folder.')
    parser.add_argument('-fwhm_in', dest='fwhm_in', required=True, type=
        float, help='Name of the output folder.')
    parser.add_argument('-mu_diffpointing', dest='mu_diffpointing',
        required=True, type=float, help=
        'Magnitude of the differential pointing (arcsecond).')
    parser.add_argument('-sigma_diffpointing', dest='sigma_diffpointing',
        required=True, type=float, help=
        'Width of the differential pointing (arcsecond).')
    parser.add_argument('-seed_diffpointing', dest='seed_diffpointing',
        required=True, type=int, help='Seed to generate differential pointing.'
        )


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 reboot_instance(instanceName=None):
    """
    Restarts a specific instance. When your Amazon Lightsail instance is finished rebooting, Lightsail assigns a new public IP address. To use the same IP address after restarting, create a static IP address and attach it to the instance.
    See also: AWS API Documentation

    :example: response = client.reboot_instance(
        instanceName='string'
    )

    :type instanceName: string
    :param instanceName: [REQUIRED]
            The name of the instance to reboot.

    :rtype: dict
    :return: {
        'operations': [
            {
                'id': 'string',
                'resourceName': 'string',
                'resourceType': 'Instance'|'StaticIp'|'KeyPair'|'InstanceSnapshot'|'Domain'|'PeeredVpc',
                'createdAt': datetime(2015, 1, 1),
                'location': {
                    'availabilityZone': 'string',
                    'regionName': 'us-east-1'|'us-west-1'|'us-west-2'|'eu-west-1'|'eu-central-1'|'ap-south-1'|'ap-southeast-1'|'ap-southeast-2'|'ap-northeast-1'|'ap-northeast-2'
                },
                'isTerminal': True|False,
                'operationDetails': 'string',
                'operationType': 'DeleteInstance'|'CreateInstance'|'StopInstance'|'StartInstance'|'RebootInstance'|'OpenInstancePublicPorts'|'PutInstancePublicPorts'|'CloseInstancePublicPorts'|'AllocateStaticIp'|'ReleaseStaticIp'|'AttachStaticIp'|'DetachStaticIp'|'UpdateDomainEntry'|'DeleteDomainEntry'|'CreateDomain'|'DeleteDomain'|'CreateInstanceSnapshot'|'DeleteInstanceSnapshot'|'CreateInstancesFromSnapshot',
                'status': 'NotStarted'|'Started'|'Failed'|'Completed',
                'statusChangedAt': datetime(2015, 1, 1),
                'errorCode': 'string',
                'errorDetails': 'string'
            },
        ]
    }

    """
    pass


@classmethod
def _get_backend_owner(cls):
    """
        return base class that we're actually switching backends on
        (needed in since backends frequently modify class attrs,
        and .set_backend may be called from a subclass).
        """
    if not cls._backend_mixin_target:
        raise AssertionError('_backend_mixin_target not set')
    for base in cls.__mro__:
        if base.__dict__.get('_backend_mixin_target'):
            return base
    raise AssertionError(
        "expected to find class w/ '_backend_mixin_target' set")


@classmethod
def get_backend_ids(cls, config):
    """Returns all configured device_id."""
    rep_list = cls(config)
    backend_ids = []
    for item in rep_list.devices:
        backend_ids.append(item.backend_id)
    return backend_ids


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 __call__():
    """Return an edition."""


def getLambdaT(m1, m2, Lambda1, Lambda2):
    """
    This function converts the Lambda1, Lambda2, mass1, mass2
    to Lambda tilde.
    """
    LambdaTilde = 2 ** 5 / (26 * (m1 + m2) ** 5)
    LambdaTilde *= (m1 ** 5 + 12 * m2 * m1 ** 4) * Lambda1 + (m2 ** 5 + 12 *
        m1 * m2 ** 4) * Lambda2
    return LambdaTilde


def enable_revise():
    """
    (Re-)enable Revise.jl integration.

    IPython magic must be loaded with ``JuliaMagics.revise = True`` option.
    """
    global revise_errors
    revise_errors = 0


@classmethod
def import_set(cls, dset, in_stream):
    """Returns dataset from DataFrame."""
    dset.wipe()
    dset.dict = in_stream.to_dict(orient='records')


def is_quantity(val):
    """Is ``val`` a quantity (int, float, datetime, etc) (not str, bool)?

    Relies on presence of __sub__.
    """
    return hasattr(val, '__sub__')


def lambd_NH3_SO4_CB89(T, P):
    """n-a: ammonia sulfate [CB89]."""
    lambd = 0.14
    valid = T == 298.15
    return lambd, valid


def gen_bit_values(number):
    """
	Return a zero or one for each bit of a numeric value up to the most
	significant 1 bit, beginning with the least significant bit.
	"""
    while number:
        yield number & 1
        number >>= 1


def clear_order(dataset, node, api_key=None):
    """
    This method is used to clear order information from the item basket.

    :param dataset:

    :param node:

    :param api_key:
        API key is required.
    """
    raise NotImplementedError


def _handle(request, handler, *rest):
    """invoke the next handler"""
    return handler(request, *rest)


@classmethod
def parse_bytes(cls, data: bytes):
    """
        Parse received Protocol Interest Packet from JSON format and convert it into ProtocolInterest object
        """
    source = data['SOURCE']
    group = data['GROUP']
    sn = data['SN']
    return cls(source, group, sn)


def body_close():
    """close the main logic"""
    pass


def update_default_branch(repositoryName=None, defaultBranchName=None):
    """
    Sets or changes the default branch name for the specified repository.
    See also: AWS API Documentation

    :example: response = client.update_default_branch(
        repositoryName='string',
        defaultBranchName='string'
    )

    :type repositoryName: string
    :param repositoryName: [REQUIRED]
            The name of the repository to set or change the default branch for.

    :type defaultBranchName: string
    :param defaultBranchName: [REQUIRED]
            The name of the branch to set as the default.

    """
    pass


def abort():
    """Abort the current transaction.

        In explicit mode, if a transaction hasn't begun, a
        `NoTransaction` exception will be raised.
        """


def compare_tracking_ids(remote_ids, local_ids):
    """ Compare the lists of the tracking_ids from a remote and a local version of a dataset
        :argument remote_ids: list of remote tracking_ids
        :argument local_ids: list of local tracking_ids
        :return: result set
    """
    return set(remote_ids).symmetric_difference(local_ids)


def getExtraHeaders():
    """ Get extra headers which do not fall in other special categories
   """
    extraHeaders = ['ROOT/TSeq.hxx', 'ROOT/StringConv.hxx']
    code = '// Extra headers\n'
    for extraHeader in extraHeaders:
        code += '#include "%s"\n' % extraHeader
    return code


def score(*args):
    """Get score of core-periphery pairs.

		Parameters
		----------
		G : Graph object.
		c : Dict object,  the keys and values of which are the name of node and its ID of belonging core-periphery pair.

		Returns
		-------
		q : List. q[i] is the quality of core-periphery pair i.

		"""
    self = args[0]
    if len(args) == 1:
        return self.qs_
    else:
        G = args[1]
        c = args[2]
        x = args[3]
        return self._score(G, c, x)


def get_motif_coordinates(end_site, motif_def, pairing,
    motif_upstream_extension, motif_downstream_extension, min_target_length):
    """
    Returns motif coordinates based on end_site (1-based)
    """
    if motif_def is None:
        motif_def = 'seed'
    if motif_def == 'seed' or motif_def == 'seed_extended':
        mirna_start_pairing = 0
        if motif_def == 'seed':
            for p in pairing:
                if p == 0:
                    mirna_start_pairing += 1
                else:
                    break
        start_motif = end_site - len(pairing) + 1 - motif_upstream_extension
        end_motif = end_site - mirna_start_pairing + motif_downstream_extension
    elif motif_def == 'site':
        start_motif = (end_site - min_target_length + 1 -
            motif_upstream_extension)
        end_motif = end_site + motif_downstream_extension
    return start_motif, end_motif


@classmethod
def extract(cls, obj):
    """ Extract span context from the given object

        :param Any obj: Object to use as context
        :return: a SpanContext instance extracted from the inner span object or None if no
            such span context could be found.
        """
    span = cls.extract_span(obj)
    if span:
        return span.context


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

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


def calculate_pct_references(df, pct_reference):
    """
    Not used yet.  Given a total number of reference sequences this function
    will divide the sseqids by the reference sequence
    count for a pct_reference.
    """
    reference_count = df[['tax_id']].drop_duplicates()
    reference_count = reference_count.join(pct_reference, on='tax_id')
    reference_count = reference_count['count'].sum()
    sseqid_count = float(len(df['sseqid'].drop_duplicates()))
    df['pct_reference'] = sseqid_count / reference_count
    return df


def plot_confusion_matrix(cm, classes, normalize=False, title=
    'Confusion matrix', cmap=None, print_matrix=True):
    """Check if Normalization Option is Set to True. If so, normalize the raw confusion matrix before visualizing
    #Other code should be equivalent to your previous function."""
    import itertools
    import numpy as np
    import matplotlib.pyplot as plt
    if cmap == None:
        cmap = plt.get_cmap('Blues')
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, (np.newaxis)]
        print('Normalized confusion matrix')
    else:
        print('Confusion matrix, without normalization')
    print(cm)
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)
    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.0
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt), horizontalalignment='center',
            color='white' if cm[i, j] > thresh else 'black')
    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.show()


@classmethod
def available(cls):
    """returns True if PulseAudio is available and running on the system"""
    try:
        from audiotools.output import PulseAudio
        return True
    except ImportError:
        return False


def xml_check_type(xml_doc_a, xml_doc_b, xpath):
    """Check for the type."""
    if xml_doc_a.nodeType != xml_doc_b.nodeType:
        return False, 'Node types differ [%s] != [%s] at [%s]' % (xml_doc_a
            .nodeType, xml_doc_b.nodeType, xpath)
    return None, None


def read_genome_dir(genome_dir_file):
    """Parse genome dir file.

    """
    genome_dirs = {}
    for line in open(genome_dir_file):
        line_split = line.rstrip().split('\t')
        genome_dirs[line_split[0]] = line_split[1]
    return genome_dirs


def geom_list_2_geom(geom_list):
    """
    Join a list of md.Trajectory objects to one single trajectory

    Parameters
    ----------

    geom_list : list of md.Trajectory objects, each can have the arbitrary geom.n_frames

    Returns
    -------

    geom : of md.Trajectory object
    """
    assert isinstance(geom_list, list)
    geom = geom_list[0]
    for jgeom in geom_list[1:]:
        geom = geom.join(jgeom)
    return geom


def synchronize_upload(client, source, destination):
    """ Synchronize remote files with a local directory.

    Long description.
    """
    raise NotImplementedError


@staticmethod
def setValue(value: int):
    """ Replacement for real progress bar: print """
    print('{}%..'.format(value), end='')


def lambd_NH3_ClO4_CB89(T, P):
    """n-a: ammonia perchlorate [CB89]."""
    lambd = -0.056
    valid = T == 298.15
    return lambd, valid


def _bbox2points(xmin, ymin, xmax, ymax):
    """Get the corners of a bbox. Points than define it.
    """
    return [(xmin, ymin), (xmax, ymin), (xmin, ymax), (xmax, ymax)]


def key():
    """Returns string identifier key that marks unique item entries (e.g. primary key field name)"""


def _convert_meth(fun):
    """hide obj-address from functions."""
    return 'meth: ', fun.__qualname__


def experts_range():
    """
    Returns the expert IDs to check in the FantasyPros URL. Maybe try to refine this in the future.
    """
    return range(1000)


@classmethod
def z_unit_vector(cls):
    """Returns the unit vector (0 | 0 | 1)"""
    return cls(0, 0, 1)


def process(ids, catalogs, limit):
    """Process up to limit objects, returning the number processed

        The first argument is an object with a getObject(id) method.

        Catalogs is a multi-iterable collection of
        zope.index.interfaces.IInjection objects to be updated.
        """


def str_append(s, char, n):
    """
        from xdict.utils import *
        str_append('a','s',3)
    """
    append = ''
    for i in range(1, n + 1):
        append = ''.join((append, char))
    return ''.join((s, append))


def ThingsToChooseFrom(ws):
    """Yields two-tuples of things to choose from, the second being weight."""
    for element in ws.elements:
        yield element, 20
    for gp in ws.groups:
        yield gp, gp.strength


def get_func_name(func):
    """Return a name which includes the module name and function name."""
    func_name = getattr(func, '__name__', func.__class__.__name__)
    module_name = func.__module__
    if module_name is not None:
        module_name = func.__module__
        return '{}.{}'.format(module_name, func_name)
    return func_name


def addon_keymap_register(keymap_data):
    """See ‘blender_defaults.py’ for examples of the format this takes.

    """
    pass


def dt(t):
    """
Computes difference between consecutive points in the time series.

:param t: input times
:param y: input y-values
    """
    dtt = []
    for i in range(t.size):
        if i > 0:
            dtt.append(t[i] - t[i - 1])
    return dtt


def Pbar2dbar(Pbar):
    """Convert pressure from bar to dbar."""
    return Pbar * 10.0


def validate(cls):
    """To be implemented in derived class."""


@staticmethod
def _get_dep_to_dot_name_mapping(dependencies):
    """ Creates mapping between Dependency classes and names used in DOT graph
        """
    dot_name_to_deps = {}
    for dep in dependencies:
        dot_name = dep.name
        if dot_name not in dot_name_to_deps:
            dot_name_to_deps[dot_name] = [dep]
        else:
            dot_name_to_deps[dot_name].append(dep)
    dep_to_dot_name = {}
    for dot_name, deps in dot_name_to_deps.items():
        for idx, dep in enumerate(deps):
            dep_to_dot_name[dep] = dep.get_custom_name(idx)
    return dep_to_dot_name


@classmethod
def hash(cls, hash_cls, key, data, **kwargs):
    """Return hash of data from byte string or unicode string."""
    if isinstance(data, str):
        data = data.encode('utf-8')
    ctx = cls(hash_cls, key, **kwargs)
    ctx.update(data)
    return ctx.finalize()


def PrefixNotation(significand, prefix=''):
    """significand -> float
prefix  -> str
return the corresponding decimal number -> float

prefix is one of :
'p' pico, 'n', 'u' or 'µ' micro, 'm', 'k', 'M' mega, 'G', 'T', '' default

>>> from dcelectricity import dc_en as dc
>>> dc.PrefixNotation(20, 'm')  # 0.02
>>> dc.PrefixNotation(50, 'k')  # 50000
>>> dc.PrefixNotation(-10000)   # -10000
"""
    prefixes = {'': 1, 'p': 1e-12, 'n': 1e-09, 'u': 1e-06, 'µ': 1e-06, 'm':
        0.001, 'k': 1000.0, 'M': 1000000.0, 'G': 1000000000.0, 'T':
        1000000000000.0}
    return significand * prefixes[prefix]


def render_item(node, linkinfo):
    """Callback function used by render().
		node : Repeater -- the copy of the rep:item node to manipulate
		linkinfo : tuple of string -- a tuple of form: (URI, name)
	"""
    url, name = linkinfo
    node.link.atts['href'] = url
    node.link.text = name


def deserialize_datetime(string):
    """Deserializes string to datetime.

    The string should be in iso8601 datetime format.

    :param string: str.
    :type string: str
    :return: datetime.
    :rtype: datetime
    """
    try:
        from dateutil.parser import parse
        return parse(string)
    except ImportError:
        return string


def decorate(string, decoration='=', n1=10, n2=None):
    """
    Decorate a string to emphasise it

    Args:
        :string: string to decorate
        :decoration: string used
        :n1: prefix multiplier
        :n2: suffix multiplier

    Returns:
        :mod_string: modified string
    """
    if not isinstance(string, str):
        raise TypeError("'string' must be of type str")
    if not isinstance(decoration, str):
        raise TypeError("'decoration' must be of type str")
    if not isinstance(n1, int):
        raise TypeError("'n1' must be of type int")
    if n2 is None:
        n2 = n1
    mod_string = decoration * n1 + ' ' + string + ' ' + decoration * n2
    return mod_string


def _ensure_bytes(s, encoding):
    """
    Ensure *s* is a bytes string.  Encode using *encoding* if it isn't.
    """
    if isinstance(s, bytes):
        return s
    return s.encode(encoding)


def mask_characters(expression, search_text, target_text, mask_char):
    """Mask characters found by a regular expression with mask character. Mask characters will equal length of masked
    string.
    A different target text to search text may be used, but the developer must ensure that they are compatible.
    This feature may be used to handle combinations of N mask_char(s) differently

    :param expression: regex expression
    :param search_text: text to search for matches
    :param target_text: text to apply mask to
    :param mask_char: character to replace masked characters
    """
    matches = []
    pos = 0
    masked_text = ''
    for match in expression.finditer(search_text):
        matches.append(match)
        masked_text += target_text[pos:match.start()] + mask_char * (match.
            end() - match.start())
        pos = match.end()
    masked_text += target_text[pos:]
    return masked_text, matches


def safelower(s):
    """
    As string.lower(), but return `s` if something goes wrong.
    """
    try:
        return s.lower()
    except AttributeError:
        return s


def admin_get_user(UserPoolId=None, Username=None):
    """
    Gets the specified user by user name in a user pool as an administrator. Works on any user.
    Requires developer credentials.
    See also: AWS API Documentation

    :example: response = client.admin_get_user(
        UserPoolId='string',
        Username='string'
    )

    :type UserPoolId: string
    :param UserPoolId: [REQUIRED]
            The user pool ID for the user pool where you want to get information about the user.

    :type Username: string
    :param Username: [REQUIRED]
            The user name of the user you wish to retrieve.

    :rtype: dict
    :return: {
        'Username': 'string',
        'UserAttributes': [
            {
                'Name': 'string',
                'Value': 'string'
            },
        ],
        'UserCreateDate': datetime(2015, 1, 1),
        'UserLastModifiedDate': datetime(2015, 1, 1),
        'Enabled': True|False,
        'UserStatus': 'UNCONFIRMED'|'CONFIRMED'|'ARCHIVED'|'COMPROMISED'|'UNKNOWN'|'RESET_REQUIRED'|'FORCE_CHANGE_PASSWORD',
        'MFAOptions': [
            {
                'DeliveryMedium': 'SMS'|'EMAIL',
                'AttributeName': 'string'
            },
        ]
    }

    :returns:
    UNCONFIRMED - User has been created but not confirmed.
    CONFIRMED - User has been confirmed.
    ARCHIVED - User is no longer active.
    COMPROMISED - User is disabled due to a potential security threat.
    UNKNOWN - User status is not known.

    """
    pass


def add_push_parser(sub_parser):
    """
    Adds a sub-parser for the "push" sub-command to the parser provided.

    :param sub_parser: the parser to add to
    :type sub_parser: <class 'argparse.ArgumentParser'>
    """
    push_parser = sub_parser.add_parser('push', help='Push file to remote')
    push_parser.add_argument('remote', help='remote to push')
    push_parser.add_argument('-k', '--key', help=
        'key of file to push (from .surround/config.yaml)')


def get_field_info(field_file):
    """
    A utility for easily extracting information about the host model from a
    Django FileField (or subclass). This is especially useful for when you want
    to alter processors based on a property of the source model. For example::

        class MySpec(ImageSpec):
            def __init__(self, source):
                instance, attname = get_field_info(source)
                self.processors = [SmartResize(instance.thumbnail_width,
                                               instance.thumbnail_height)]

    """
    return getattr(field_file, 'instance', None), getattr(getattr(
        field_file, 'field', None), 'attname', None)


def p_corrected_bonf(p, n):
    """
	Bonferroni-corrected *p* value.

	.. warning:: This correction assumes independence amongst multiple tests.

	:Parameters:

	- *p* --- probability value computed from one of multiple tests
	- *n* --- number of tests

	:Returns:

	- Bonferroni-corrected *p* value.

	:Example:

	>>> p = spm1d.util.p_corrected_bonf(0.03, 8)    # yields p = 0.216
	"""
    if p <= 0:
        return 0
    elif p >= 1:
        return 1
    else:
        pBonf = 1 - (1.0 - p) ** n
        pBonf = max(0, min(1, pBonf))
        return pBonf


def addDeploymentOptions(parser):
    """
    Add report-specific options to the parser.
    """
    from optparse import OptionGroup
    group = OptionGroup(parser, 'Deployment Options')
    group.add_option('--rsync-dest', action='store', metavar='DEST', help=
        'deploy artifacts to this location using rsync (accepts the same format specification as --build-id)'
        )
    parser.add_option_group(group)
    parser.set_defaults(rsync_dest=None)
    return parser


def sizeofints(sizes):
    """
    Number of bits required to pack a list of integers with max values sizes.

    """
    p = 1
    for s in sizes:
        p = p * s
    i = int(p).bit_length()
    return i


def get_required_capabilities(data: dict):
    """
    Get capabilities for a given cloud formation template for the
    "create_stack" call
    """
    capabilities = []
    for _, config in data.get('Resources', {}).items():
        if config.get('Type').startswith('AWS::IAM'):
            if config.get('Properties', {}).get('RoleName'):
                capabilities.append('CAPABILITY_NAMED_IAM')
            else:
                capabilities.append('CAPABILITY_IAM')
    return capabilities


def print_dict(dict_):
    """Print pretty-printed FTYPE dictionary."""
    print('FTYPE = {')
    fmt = """    %r: {
        'pygments': %r,
        'ctags': %r,
    },"""
    for k, v in dict_.items():
        v1 = v['pygments']
        v2 = v['ctags']
        print(fmt % (k, v1, v2))
    print('}')


def get_sharemap():
    """Return a dict mapping share identifier to set of IServer
        instances. This indicates which servers were given which shares. For
        immutable files, the shareid is an integer (the share number, from 0
        to N-1). For mutable files, it is a string of the form
        'seq%d-%s-sh%d', containing the sequence number, the roothash, and
        the share number."""


def rubygems_download_url(name, version, platform=None, repo=
    'https://rubygems.org/downloads'):
    """
    Return a .gem download URL given a name, version, and optional platform (e.g. java)
    and a base repo URL.

    For example: https://rubygems.org/downloads/mocha-1.7.0.gem
    """
    repo = repo.rstrip('/')
    name = name.strip().strip('/')
    version = version.strip().strip('/')
    version_plat = version
    if platform and platform != 'ruby':
        version_plat = '{version}-{platform}'.format(**locals())
    return '{repo}/{name}-{version_plat}.gem'.format(**locals())


def foldOneLine(outbuf, input, lineLength=75):
    """
    Folding line procedure that ensures multi-byte utf-8 sequences are not broken across lines

    TO-DO: This all seems odd. Is it still needed, especially in python3?
    """
    if len(input) < lineLength:
        try:
            outbuf.write(bytes(input, 'UTF-8'))
        except Exception:
            outbuf.write(input)
    else:
        start = 0
        written = 0
        while written < len(input):
            offset = start + lineLength - 1
            if offset >= len(input):
                line = input[start:]
                try:
                    outbuf.write(bytes(line, 'UTF-8'))
                except Exception:
                    outbuf.write(line)
                written = len(input)
            else:
                line = input[start:offset]
                try:
                    outbuf.write(bytes(line, 'UTF-8'))
                    outbuf.write(bytes('\r\n ', 'UTF-8'))
                except Exception:
                    outbuf.write(line)
                    outbuf.write('\r\n ')
                written += offset - start
                start = offset
    try:
        outbuf.write(bytes('\r\n', 'UTF-8'))
    except Exception:
        outbuf.write('\r\n')


def w(event):
    """ show user data. """
    from bot.space import users
    u = users.fetch(event.userhost)
    if u:
        event.reply(u)
    else:
        event.reply('no matching user found.')


def toHex(val):
    """Converts the given value (0-255) into its hexadecimal representation"""
    hex = '0123456789abcdef'
    return hex[int(val / 16)] + hex[int(val - int(val / 16) * 16)]


def build_coreference(reference_id: int) ->dict:
    """Build a frame for a coreference structure"""
    return {'id': reference_id, 'representative': {'tokens': []},
        'referents': []}


def get_lomb_trend(lomb_model):
    """Get the linear trend of a fitted Lomb-Scargle model."""
    return lomb_model['trend']


def lcut(s, sub):
    """
    Cuts off the substring `sub` if string `s` starts with it.
    """
    len_sub = len(sub)
    if s[:len_sub] == sub:
        return s[len_sub:]
    return s


def doc_view(doc_id: str=''):
    """Load online reference docs

    :param doc_id: Doc ID
    :type doc_id: str
    """
    pass


def locate_significant_digit_after_decimal(value):
    """ Get location at which significant digit start after decimal

	Parameters
	----------
	value : float
		Input value

	Returns
	-------
	value : int
		Number of zeros after which digit start in a small decimal number.

	"""
    location = 0
    base = 0
    while base <= 0:
        base = int(abs(value) * 10 ** location)
        location = location + 1
    return location - 1


@classmethod
def fetch_and_load(this_class, model_name, models_directory=None, verbose=
    False, extra_loading_options=None):
    """Downloads, installs, and creates a RerankingParser object for
        a specified model using ModelFetcher.download_and_install_model.
        model_name must be one of the defined models in ModelFetcher
        and models_directory is a directory where the model will
        be installed. By default, models will be installed to
        "~/.local/share/bllipparser". Setting verbose=True will
        cause ModelFetcher to be print additional details. Finally,
        extra_loading_options is a dictionary of keyword arguments
        passed to RerankingParser.from_unified_model_dir to customize
        the parsing models."""
    from .ModelFetcher import download_and_install_model
    model_dir = download_and_install_model(model_name, models_directory,
        verbose)
    kwargs = extra_loading_options or {}
    return this_class.from_unified_model_dir(model_dir, **kwargs)


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 throw_if_file_access_not_allowed(file_path, logdir, has_auth_group):
    """Throws an error if a file cannot be loaded for inference.

  Args:
    file_path: A file path.
    logdir: The path to the logdir of the TensorBoard context.
    has_auth_group: True if TensorBoard was started with an authorized group,
        in which case we allow access to all visible files.

  Raises:
    InvalidUserInputError: If the file is not in the logdir and is not globally
        readable.
  """
    return


def delta_seconds(before, after):
    """Return the difference between two timing objects.

    Compute the difference in seconds between two date, time, or
    datetime objects (as a float, to microsecond resolution).
    """
    delta = after - before
    return delta.total_seconds()


def theta_H_Me4N_PK74(T, P):
    """c-c': hydrogen tetramethylammonium [PK74]."""
    theta = 0.0
    valid = T == 298.15
    return theta, valid


def clipboard_paste():
    """Pastes nodes from the clipboard to the active node tree

    """
    pass


def is_object(t):
    """A fast comparison to check if a Plum type is `object`.

    Args:
        t (ptype): Type to check.

    Returns:
        bool: `t` is `object`.
    """
    return t.get_types() == (object,)


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 _convert_ceil(builder, node, graph, err):
    """
    convert to CoreML Ceil Layer:
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L5018
    """
    builder.add_ceil(name=node.name, input_name=node.inputs[0], output_name
        =node.outputs[0])


def _set2str(val):
    """convert an iterable to the repr string of a set."""
    elms = sorted(list(val))
    return 'set(%s)' % repr(elms)


@classmethod
def from_string(cls, wf: str, validate: bool=True) ->'Workflow':
    """Create a Workflow from a YAML string."""
    body = {'data': wf}
    return cls.__deserialize(body, validate=validate)


def rmdir(path):
    """Remove a directory.

        If it is not possible or allowed to remove the directory, an `OSError`
        should be raised describing the reason of failure.
        """


def render_layer_add():
    """Add a render layer

    """
    pass


def header(content_type='text/html', filename=None):
    """ Return the header needed for a CGI application.
			@param content_type: The type of content delivered (optional, defaults to text/html)
			@param filename: Set the content to be a downloadable file (optional)
	"""
    output = 'Content-Type: ' + str(content_type) + '; charset=utf-8\n\n'
    if filename:
        output = ('Content-Disposition: attachment; filename=' + filename +
            '\n' + output)
    return output


def applydiff(tokens, deltas):
    """tokens can be a string or a list of strings.  deltas is [Delta,...]. Delta.text is actually a tokenlist of the same type as tokens (string or list of string).  If tokens & tokenslist are strings, must be unicode for the offsets to match what JS produces.    (If they're lists, it doesn't matter; the offsets are relative to the lists, not internal to the strings)."""
    sizechange = 0
    for a, b, replace in deltas:
        tokens = tokens[:a + sizechange] + replace + tokens[b + sizechange:]
        sizechange += len(replace) - (b - a)
    return tokens


@classmethod
def split(cls, dataset, start, end, datatype, **kwargs):
    """
        Splits a multi-interface Dataset into regular Datasets using
        regular tabular interfaces.
        """
    objs = []
    if datatype is None:
        for d in dataset.data[start:end]:
            objs.append(dataset.clone(d, datatype=cls.subtypes))
        return objs
    elif not dataset.data:
        return objs
    ds = cls._inner_dataset_template(dataset)
    for d in dataset.data:
        ds.data = d
        if datatype == 'array':
            obj = ds.array(**kwargs)
        elif datatype == 'dataframe':
            obj = ds.dframe(**kwargs)
        elif datatype == 'columns':
            if ds.interface.datatype == 'dictionary':
                obj = dict(d)
            else:
                obj = ds.columns(**kwargs)
        else:
            raise ValueError('%s datatype not support' % datatype)
        objs.append(obj)
    return objs


@staticmethod
def __date_time_str(dt):
    """
        reformat the date_tiem string
        example: 1/1/2018 01:00:00 -> 1/1/2018 00:00:00
        :param dt:
        :return:
        """
    date_time_item = dt.split(' ')
    date_str = date_time_item[0]
    time_str = date_time_item[1]
    time_item = time_str.split(':')
    hr = time_item[0]
    hr_int = int(hr)
    hr_int = hr_int - 1
    return date_str + ' ' + str(hr_int) + ':' + time_item[1] + ':' + time_item[
        2]


def set_flags(obj, flag_field, flags):
    """Will process the flags and set attributes in the object accordingly.

    The object "obj" will gain attributes named after the flags provided in
    "flags" and valued True/False, matching the results of applying each
    flag value from "flags" to flag_field.
    """
    for flag, value in flags:
        if value & flag_field:
            obj.__dict__[flag] = True
        else:
            obj.__dict__[flag] = False


def metadata_listdir(name):
    """List of metadata names in the directory (like ``os.listdir()``)"""


def is_palindrome(n):
    """
    Checks if a number is plaindrome -- reads the same backwards
    @arg n  The number we check
    @ret    Boolean
    """
    return int(str(n)[::-1]) == n


def collapse_overlapping_ranges(ranges):
    """ Collapse the list of (possibly overlapping) selected ranges into
    a monotonically increasing set of non-overlapping ranges
    """
    opt = []
    start, end = None, None
    for next_start, next_end in sorted(ranges):
        if next_start > next_end:
            next_start, next_end = next_end, next_start
        if start is None:
            start, end = next_start, next_end
        elif next_start > end:
            opt.append((start, end))
            start, end = next_start, next_end
        elif next_end > end:
            end = next_end
    if start is not None:
        opt.append((start, end))
    return opt


def read_scan(filename):
    """
    Function that returns the number of scan that have been recorded
    It is used to see wether the number of recorded points correspond to the L_20 parameter
    """
    from xml.dom import minidom
    xmldoc = minidom.parse(filename)
    x = xmldoc.documentElement
    pp = {}
    children = x.childNodes
    count_scan = 0
    for child in children:
        if child.nodeName == 'scan':
            count_scan += 1
    return count_scan


def _mutate_array_js(array, ev):
    """ Logic to mutate an list-like or array-like property in-place, in JS.
    """
    is_nd = hasattr(array, 'shape') and hasattr(array, 'dtype')
    mutation = ev.mutation
    index = ev.index
    objects = ev.objects
    if is_nd is True:
        if mutation == 'set':
            raise NotImplementedError('Cannot set nd array in-place')
        elif mutation in ('extend', 'insert', 'remove'):
            raise NotImplementedError('Cannot resize nd arrays')
        elif mutation == 'replace':
            raise NotImplementedError('Cannot replace items in nd array')
    else:
        if mutation == 'remove':
            assert isinstance(objects, float)
        elif not isinstance(objects, list):
            raise TypeError(
                'Inplace list/array mutating requires a list of objects.')
        if mutation == 'set':
            array.splice(0, len(array), *objects)
        elif mutation == 'insert':
            array.splice(index, 0, *objects)
        elif mutation == 'remove':
            array.splice(index, objects)
        elif mutation == 'replace':
            array.splice(index, len(objects), *objects)
        else:
            raise NotImplementedError(mutation)


def _get_association_nodes(digraph, sub, predicate, obj):
    """
    Given a subject, predicate, object, retrieve the OBAN association
    node from the evidence graph
    """
    subject_assocs = set()
    object_assocs = set()
    predicate_assocs = set()
    union_assoc = set()
    if predicate['pred'] in digraph.node:
        for neighbor, edges in digraph.pred[sub].items():
            for edge in edges.values():
                if edge['pred'] == 'OBAN:association_has_subject':
                    subject_assocs.add(neighbor)
        for neighbor, edges in digraph.pred[obj].items():
            for edge in edges.values():
                if edge['pred'] == 'OBAN:association_has_object':
                    object_assocs.add(neighbor)
        for neighbor, edges in digraph.pred[predicate['pred']].items():
            for edge in edges.values():
                if edge['pred'] == 'OBAN:association_has_predicate':
                    predicate_assocs.add(neighbor)
        union_assoc = subject_assocs & object_assocs & predicate_assocs
    return union_assoc


@classmethod
def normalize_field_names(cls, torrent_info):
    """Translates from torrent fields names in terms of RPC to field names in term of torrt.
        Updates accordingly a given torrent_info.

        :param torrent_info: dict
        :return:
        """
    for old_name, new_name in cls.torrent_fields_map.items():
        if old_name in torrent_info:
            torrent_info[new_name] = torrent_info[old_name]


def writeJackalScapFile(mutationData=None, filename='1xxx_scap.list',
    options=None):
    """
    writing a scap file for, i.e., generating a mutated protein
    """
    file = open(filename, 'w')
    for chainID, code1, resNumb, code2 in mutationData:
        str = '%s, %d, %s\n' % (chainID, resNumb, code2)
        file.write(str)
    file.close()


def validate_method(method, supported_methods):
    """Raises a `ValueError` if a method is not supported.

    Parameters
    ----------
    method : str
        The method specified by the user.
    supported_methods : list of str
        The methods supported.  All method names must be lowercase.

    Returns
    -------
    method : str
        Will return the method name if it is supported.
    """
    method = method.lower()
    if method in supported_methods:
        return method
    raise ValueError("method '{}' is not supported; must be one of {}".
        format(method, supported_methods))


def lift_calc(PPV, PRE):
    """
    Calculate lift score.

    :param PPV:  precision or positive predictive value
    :type PPV : float
    :param PRE: Prevalence
    :type PRE : float
    :return: lift score as float
    """
    try:
        return PPV / PRE
    except (ZeroDivisionError, TypeError):
        return 'None'


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

    The ".dev0" means dirty.

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


def compute_identification_statistics_for_non_accumulated_fragments(fragments,
    assigner, number_of_animals=None):
    """Given the predictions associated to the images in each (individual)
    fragment in the list fragments if computes the statistics necessary for the
    identification of fragment.

    Parameters
    ----------
    fragments : list
        List of individual fragment objects
    assigner : <GetPrediction object>
        The assigner object has as main attributes the list of predictions
        associated to `images` and the the corresponding softmax vectors
    number_of_animals : int
        number of animals to be tracked
    """
    counter = 0
    for fragment in fragments:
        if not fragment.used_for_training and fragment.is_an_individual:
            next_counter_value = counter + fragment.number_of_images
            predictions = assigner.predictions[counter:next_counter_value]
            softmax_probs = assigner.softmax_probs[counter:next_counter_value]
            fragment.compute_identification_statistics(predictions,
                softmax_probs, number_of_animals=number_of_animals)
            counter = next_counter_value


def bench5(x):
    """A benchmark function for test purposes.

        f(x) = float(x[0]) ** 2 + x[1] ** 2

    where x is a string. It has a single minima with f(x) = 0 at x[0] = "0"
    and x[1] = "0"
    This benchmark is used for checking support of mixed spaces.
    """
    return float(x[0]) ** 2 + x[1] ** 2


def issorted(seq, key=None):
    """
    returns True if seq is sorted
    """
    lastx = -float('inf')
    if key is not None:
        for x in seq:
            x = key(x)
            if x < lastx:
                return False
            lastx = x
        return True
    else:
        for x in seq:
            if x < lastx:
                return False
            lastx = x
        return True


def get(isamAppliance, check_mode=False, force=False):
    """
    Retrieving the SNMP Monitoring configuration
    """
    return isamAppliance.invoke_get(
        'Retrieving the SNMP Monitoring configuration', '/snmp/v1')


def get_interface_type(interface):
    """Gets the type of interface
    """
    if interface.upper().startswith('ET'):
        return 'ethernet'
    elif interface.upper().startswith('VL'):
        return 'svi'
    elif interface.upper().startswith('LO'):
        return 'loopback'
    elif interface.upper().startswith('MG'):
        return 'management'
    elif interface.upper().startswith('MA'):
        return 'management'
    elif interface.upper().startswith('PO'):
        return 'portchannel'
    elif interface.upper().startswith('NV'):
        return 'nve'
    else:
        return 'unknown'


@staticmethod
def clean_isatab_field_names(field_names):
    """Fixes ISA-Tab header names. Sometimes Pandas adds suffixes to them
        uneccessarily or other junk

        :param field_names: List of field header names
        :return: Fixed field names
        """
    for i, field_name in enumerate(field_names):
        if field_name.startswith('Term Source REF'):
            field_names[i] = 'Term Source REF'
        elif field_name.startswith('Term Accession Number'):
            field_names[i] = 'Term Accession Number'
        elif field_name.startswith('Unit'):
            field_names[i] = 'Unit'
        elif 'Characteristics[' in field_name:
            if 'material type' in field_name.lower():
                field_names[i] = 'Material Type'
            else:
                try:
                    field_names[i] = field_name[field_name.rindex('.') + 1:]
                except ValueError:
                    pass
        elif 'Factor Value[' in field_name:
            try:
                field_names[i] = field_name[field_name.rindex('.') + 1:]
            except ValueError:
                pass
        elif 'Parameter Value[' in field_name:
            try:
                field_names[i] = field_name[field_name.rindex('.') + 1:]
            except ValueError:
                pass
        elif field_name.endswith('Date'):
            field_names[i] = 'Date'
        elif field_name.endswith('Performer'):
            field_names[i] = 'Performer'
        elif 'Protocol REF' in field_name:
            field_names[i] = 'Protocol REF'
        elif field_name.startswith('Sample Name.'):
            field_names[i] = 'Sample Name'
    return field_names


@staticmethod
def is_fold_trigger(block):
    """
        Checks if the block is a fold trigger.

        :param block: block to check
        :return: True if the block is a fold trigger (represented as a node in
            the fold panel)
        """
    if block is None:
        return False
    state = block.userState()
    if state == -1:
        state = 0
    return bool(state & 67108864)


def add_pkcs1_padding(message):
    """Add PKCS#1 padding to **message**."""
    padding = b''
    typeinfo = b'\x00\x01'
    separator = b'\x00'
    padding = b'\xff' * (125 - len(message))
    padded_message = typeinfo + padding + separator + message
    assert len(padded_message) == 128
    return padded_message


def md_link(node):
    """Extract a metadata link tuple from an xml node"""
    mimetype = node.find('type')
    mdtype = node.find('metadataType')
    content = node.find('content')
    if None in [mimetype, mdtype, content]:
        return None
    else:
        return mimetype.text, mdtype.text, content.text