def define_dynamic_lists(mod):
    """
    Zone_Power_Injections and Zone_Power_Withdrawals are lists of
    components that contribute to load-zone level power balance equations.
    sum(Zone_Power_Injections[z,t]) == sum(Zone_Power_Withdrawals[z,t])
        for all z,t
    Other modules may append to either list, as long as the components they
    add are indexed by [zone, timepoint] and have units of MW. Other modules
    often include Expressions to summarize decision variables on a zonal basis.
    """
    mod.Zone_Power_Injections = []
    mod.Zone_Power_Withdrawals = []


def identity_func(x):
    """The identify (a.k.a. transparent) function that returns it's input as is."""
    return x


@staticmethod
def supportedViews():
    """Overrides :meth:`.ControlMixin.supportedViews`. The
        ``CropImagePanel`` is only intended to be added to
        :class:`.OrthoPanel` views.
        """
    from fsleyes.views.orthopanel import OrthoPanel
    return [OrthoPanel]


def getfilename(filepath):
    """ Returns the file name without path and extension"""
    return filepath.split('/')[-1].split('.')[0]


@classmethod
def add_documentation(cls, argparse_obj):
    """set up argparse for command and all of its subcommands"""
    cmd_parser = super().add_documentation(argparse_obj)
    subcommands = cmd_parser.add_subparsers(title='subcommands', metavar=
        '<subcommand>', dest='subcommand')
    subcommands.required = True
    for sub_command in cls.sub_commands:
        sub_command.add_documentation(subcommands)


@classmethod
def find_free_port(cls, base_port, socket_path):
    """start base_port to lookup a free port"""
    while base_port < 60000:
        if cls.is_open(ip='127.0.0.1', port=base_port):
            base_port += 1
        else:
            try:
                cls.__check_socket('{}/{}'.format(socket_path, base_port))
                return base_port
            except FileExistsError as e:
                base_port += 1


def obtainLigandIndexes(trajectory, ligand):
    """
    Extract the indexes for the ligand in the trajectory
    :param trajectory: mdtraj trajectory
    :param ligand: name of the ligand
    :return: list of the atom indexes of the heavy atoms of the ligand
    """
    residueIndexes = []
    for residue in trajectory.topology.residues:
        if residue.name == ligand:
            for atom in residue.atoms:
                if 'H' not in atom.name:
                    residueIndexes.append(atom.index)
    return residueIndexes


def parse_modes(modes, targets=None, noargs=''):
    """Parse channel modes:

    .. code-block:: python

        >>> parse_modes('+c-n', noargs='cn')
        [('+', 'c', None), ('-', 'n', None)]
        >>> parse_modes('+c-v', ['gawel'], noargs='c')
        [('+', 'c', None), ('-', 'v', 'gawel')]
    """
    if not targets:
        targets = []
    cleaned = []
    for mode in modes:
        if mode in '-+':
            char = mode
            continue
        target = targets.pop(0) if mode not in noargs else None
        cleaned.append((char, mode, target))
    return cleaned


def get_dims(*arrays):
    """ find all dimensions from a variable list of arrays (or any object with `axes` attribute)
    Note: not in public API, but used by other modules
    """
    dims = []
    for o in arrays:
        for ax in o.axes:
            if ax.name not in dims:
                dims.append(ax.name)
    return dims


def fetch(db, templ, *args):
    """
    Run generic queries directly on the database. See the documentation
    of the dbapi module.

    :param db: a :class:`openquake.server.dbapi.Db` instance
    :param templ: a SQL query template
    :param args: arguments to pass to the template
    """
    return db(templ, *args)


def compute_scissor(window_width, window_height, image_width, image_height,
    aspect_ratio):
    """
    Used on vtkCamera when you are trying to set the viewport to only render
    to a part of the total window size. For example, this occurs when you
    have calibrated a video camera using OpenCV, on images of 1920 x 1080,
    and then you are displaying in a VTK window that is twice as wide/high.

    This was implemented in:
    `NifTK <https://cmiclab.cs.ucl.ac.uk/CMIC/NifTK/blob/master/MITK/Modules/Core/Rendering/vtkOpenGLMatrixDrivenCamera.cxx#L129>`_.

    and it appears it should also be available in:
    `VTK <https://gitlab.kitware.com/vtk/vtk/merge_requests/882>`_.

    :param window_width: in pixels
    :param window_height: in pixels
    :param image_width: in pixels
    :param image_height: in pixels
    :param aspect_ratio: relative physical size of pixels, as x/y.
    :return: scissor_x, scissor_y, scissor_width, scissor_height in pixels
    """
    width_scale = window_width / image_width
    height_scale = window_height / (image_height / aspect_ratio)
    vpw = window_width
    vph = window_height
    if width_scale < height_scale:
        vph = int(image_height / aspect_ratio * width_scale)
    else:
        vpw = int(image_width * height_scale)
    vpx = int(window_width / 2.0 - vpw / 2.0)
    vpy = int(window_height / 2.0 - vph / 2.0)
    return vpx, vpy, vpw, vph


@classmethod
def adjust_database_uri(cls, uri, selected_schema):
    """Based on a URI and selected schema, return a new URI

        The URI here represents the URI as entered when saving the database,
        ``selected_schema`` is the schema currently active presumably in
        the SQL Lab dropdown. Based on that, for some database engine,
        we can return a new altered URI that connects straight to the
        active schema, meaning the users won't have to prefix the object
        names by the schema name.

        Some databases engines have 2 level of namespacing: database and
        schema (postgres, oracle, mssql, ...)
        For those it's probably better to not alter the database
        component of the URI with the schema name, it won't work.

        Some database drivers like presto accept '{catalog}/{schema}' in
        the database component of the URL, that can be handled here.
        """
    return uri


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

    """
    pass


@classmethod
def dark_green(cls):
    """A factory method that returns a :class:`Colour` with a value of ``0x1f8b4c``."""
    return cls(2067276)


def create_segment(ApplicationId=None, WriteSegmentRequest=None):
    """
    Used to create or update a segment.

    :example: response = client.create_segment(
        ApplicationId='string',
        WriteSegmentRequest={
            'Dimensions': {
                'Attributes': {
                    'string': {
                        'AttributeType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    }
                },
                'Behavior': {
                    'Recency': {
                        'Duration': 'HR_24'|'DAY_7'|'DAY_14'|'DAY_30',
                        'RecencyType': 'ACTIVE'|'INACTIVE'
                    }
                },
                'Demographic': {
                    'AppVersion': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    },
                    'DeviceType': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    },
                    'Make': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    },
                    'Model': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    },
                    'Platform': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    }
                },
                'Location': {
                    'Country': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    }
                },
                'UserAttributes': {
                    'string': {
                        'AttributeType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    }
                }
            },
            'Name': 'string'
        }
    )

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

    :type WriteSegmentRequest: dict
    :param WriteSegmentRequest: [REQUIRED] Segment definition.
            Dimensions (dict) -- The segment dimensions attributes.
            Attributes (dict) -- Custom segment attributes.
            (string) --
            (dict) -- Custom attibute dimension
            AttributeType (string) -- The type of dimension: INCLUSIVE   Endpoints that match the criteria are included in the segment. EXCLUSIVE   Endpoints that match the criteria are excluded from the segment.
            Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
            (string) --

            Behavior (dict) -- The segment behaviors attributes.
            Recency (dict) -- The recency of use.
            Duration (string) -- The length of time during which users have been active or inactive with your app. Valid values: HR_24, DAY_7, DAY_14, DAY_30
            RecencyType (string) -- The recency dimension type: ACTIVE   Users who have used your app within the specified duration are included in the segment. INACTIVE   Users who have not used your app within the specified duration are included in the segment.

            Demographic (dict) -- The segment demographics attributes.
            AppVersion (dict) -- The app version criteria for the segment.
            DimensionType (string) -- The type of dimension: INCLUSIVE   Endpoints that match the criteria are included in the segment. EXCLUSIVE   Endpoints that match the criteria are excluded from the segment.
            Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
            (string) --

            DeviceType (dict) -- The device type criteria for the segment.
            DimensionType (string) -- The type of dimension: INCLUSIVE   Endpoints that match the criteria are included in the segment. EXCLUSIVE   Endpoints that match the criteria are excluded from the segment.
            Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
            (string) --

            Make (dict) -- The device make criteria for the segment.
            DimensionType (string) -- The type of dimension: INCLUSIVE   Endpoints that match the criteria are included in the segment. EXCLUSIVE   Endpoints that match the criteria are excluded from the segment.
            Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
            (string) --

            Model (dict) -- The device model criteria for the segment.
            DimensionType (string) -- The type of dimension: INCLUSIVE   Endpoints that match the criteria are included in the segment. EXCLUSIVE   Endpoints that match the criteria are excluded from the segment.
            Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
            (string) --

            Platform (dict) -- The device platform criteria for the segment.
            DimensionType (string) -- The type of dimension: INCLUSIVE   Endpoints that match the criteria are included in the segment. EXCLUSIVE   Endpoints that match the criteria are excluded from the segment.
            Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
            (string) --

            Location (dict) -- The segment location attributes.
            Country (dict) -- The country filter according to ISO 3166-1 Alpha-2 codes.
            DimensionType (string) -- The type of dimension: INCLUSIVE   Endpoints that match the criteria are included in the segment. EXCLUSIVE   Endpoints that match the criteria are excluded from the segment.
            Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
            (string) --

            UserAttributes (dict) -- Custom segment user attributes.
            (string) --
            (dict) -- Custom attibute dimension
            AttributeType (string) -- The type of dimension: INCLUSIVE   Endpoints that match the criteria are included in the segment. EXCLUSIVE   Endpoints that match the criteria are excluded from the segment.
            Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
            (string) --

            Name (string) -- The name of segment

    :rtype: dict
    :return: {
        'SegmentResponse': {
            'ApplicationId': 'string',
            'CreationDate': 'string',
            'Dimensions': {
                'Attributes': {
                    'string': {
                        'AttributeType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    }
                },
                'Behavior': {
                    'Recency': {
                        'Duration': 'HR_24'|'DAY_7'|'DAY_14'|'DAY_30',
                        'RecencyType': 'ACTIVE'|'INACTIVE'
                    }
                },
                'Demographic': {
                    'AppVersion': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    },
                    'DeviceType': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    },
                    'Make': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    },
                    'Model': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    },
                    'Platform': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    }
                },
                'Location': {
                    'Country': {
                        'DimensionType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    }
                },
                'UserAttributes': {
                    'string': {
                        'AttributeType': 'INCLUSIVE'|'EXCLUSIVE',
                        'Values': [
                            'string',
                        ]
                    }
                }
            },
            'Id': 'string',
            'ImportDefinition': {
                'ExternalId': 'string',
                'Format': 'CSV'|'JSON',
                'RoleArn': 'string',
                'S3Url': 'string',
                'Size': 123
            },
            'LastModifiedDate': 'string',
            'Name': 'string',
            'SegmentType': 'DIMENSIONAL'|'IMPORT',
            'Version': 123
        }
    }

    :returns:
    (dict) -- 201 response
    SegmentResponse (dict) -- Segment definition.
    ApplicationId (string) -- The ID of the application to which the segment applies.
    CreationDate (string) -- The date the segment was created in ISO 8601 format.
    Dimensions (dict) -- The segment dimensions attributes.
    Attributes (dict) -- Custom segment attributes.
    (string) --
    (dict) -- Custom attibute dimension
    AttributeType (string) -- The type of dimension: INCLUSIVE  Endpoints that match the criteria are included in the segment. EXCLUSIVE  Endpoints that match the criteria are excluded from the segment.
    Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
    (string) --

    Behavior (dict) -- The segment behaviors attributes.
    Recency (dict) -- The recency of use.
    Duration (string) -- The length of time during which users have been active or inactive with your app. Valid values: HR_24, DAY_7, DAY_14, DAY_30
    RecencyType (string) -- The recency dimension type: ACTIVE  Users who have used your app within the specified duration are included in the segment. INACTIVE  Users who have not used your app within the specified duration are included in the segment.

    Demographic (dict) -- The segment demographics attributes.
    AppVersion (dict) -- The app version criteria for the segment.
    DimensionType (string) -- The type of dimension: INCLUSIVE  Endpoints that match the criteria are included in the segment. EXCLUSIVE  Endpoints that match the criteria are excluded from the segment.
    Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
    (string) --

    DeviceType (dict) -- The device type criteria for the segment.
    DimensionType (string) -- The type of dimension: INCLUSIVE  Endpoints that match the criteria are included in the segment. EXCLUSIVE  Endpoints that match the criteria are excluded from the segment.
    Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
    (string) --

    Make (dict) -- The device make criteria for the segment.
    DimensionType (string) -- The type of dimension: INCLUSIVE  Endpoints that match the criteria are included in the segment. EXCLUSIVE  Endpoints that match the criteria are excluded from the segment.
    Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
    (string) --

    Model (dict) -- The device model criteria for the segment.
    DimensionType (string) -- The type of dimension: INCLUSIVE  Endpoints that match the criteria are included in the segment. EXCLUSIVE  Endpoints that match the criteria are excluded from the segment.
    Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
    (string) --

    Platform (dict) -- The device platform criteria for the segment.
    DimensionType (string) -- The type of dimension: INCLUSIVE  Endpoints that match the criteria are included in the segment. EXCLUSIVE  Endpoints that match the criteria are excluded from the segment.
    Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
    (string) --

    Location (dict) -- The segment location attributes.
    Country (dict) -- The country filter according to ISO 3166-1 Alpha-2 codes.
    DimensionType (string) -- The type of dimension: INCLUSIVE  Endpoints that match the criteria are included in the segment. EXCLUSIVE  Endpoints that match the criteria are excluded from the segment.
    Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
    (string) --

    UserAttributes (dict) -- Custom segment user attributes.
    (string) --
    (dict) -- Custom attibute dimension
    AttributeType (string) -- The type of dimension: INCLUSIVE  Endpoints that match the criteria are included in the segment. EXCLUSIVE  Endpoints that match the criteria are excluded from the segment.
    Values (list) -- The criteria values for the segment dimension. Endpoints with matching attribute values are included or excluded from the segment, depending on the setting for Type.
    (string) --

    Id (string) -- The unique segment ID.
    ImportDefinition (dict) -- The import job settings.
    ExternalId (string) -- A unique, custom ID assigned to the IAM role that restricts who can assume the role.
    Format (string) -- The format of the endpoint files that were imported to create this segment. Valid values: CSV, JSON
    RoleArn (string) -- The Amazon Resource Name (ARN) of an IAM role that grants Amazon Pinpoint access to the endpoints in Amazon S3.
    S3Url (string) -- A URL that points to the Amazon S3 location from which the endpoints for this segment were imported.
    Size (integer) -- The number of endpoints that were successfully imported to create this segment.

    LastModifiedDate (string) -- The date the segment was last updated in ISO 8601 format.
    Name (string) -- The name of segment
    SegmentType (string) -- The segment type: DIMENSIONAL  A dynamic segment built from selection criteria based on endpoint data reported by your app. You create this type of segment by using the segment builder in the Amazon Pinpoint console or by making a POST request to the segments resource. IMPORT  A static segment built from an imported set of endpoint definitions. You create this type of segment by importing a segment in the Amazon Pinpoint console or by making a POST request to the jobs/import resource.
    Version (integer) -- The segment version number.

    """
    pass


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

        :param FileMemberActionError val:
        :rtype: FileMemberRemoveActionResult
        """
    return cls('member_error', val)


def _storeRemote(remote, namespace):
    """Stores the remote in the namespace; reports success to console.

    """
    namespace['remote'] = remote
    namespace['manhole'].overwriteLine('Connected to the exercise server!')


@staticmethod
def _run(waterbody, datetime_time_step, logger, area_m2, time_gap_sec,
    c_in_rain, c_in_peva, c_p_t, c_p_c, c_p_h, c_p_d, c_p_s, c_p_z, c_p_sk,
    c_p_fk, c_p_gk, c_s_v_h2o_ove, c_s_v_h2o_dra, c_s_v_h2o_int,
    c_s_v_h2o_sgw, c_s_v_h2o_dgw, c_s_v_h2o_ly1, c_s_v_h2o_ly2,
    c_s_v_h2o_ly3, c_s_v_h2o_ly4, c_s_v_h2o_ly5, c_s_v_h2o_ly6):
    """
        This function was written by Thibault Hallouin but is largely inspired by the work of Eva Mockler, namely for
        the work published in: Mockler, E., O’Loughlin, F., and Bruen, M.: Understanding hydrological flow paths in
        conceptual catchment models using uncertainty and sensitivity analysis, Computers & Geosciences, 90, 66–77,
        doi:10.1016/j.cageo.2015.08.015, 2016.

        Catchment Constants
        _ area_m2                   catchment area [m2]
        _ time_gap_sec              time gap between two simulation time steps [seconds]

        Catchment Model * c_ *
        _ Hydrology
        ___ Inputs * in_ *
        _____ c_in_rain             precipitation as rain [mm/time step]
        _____ c_in_peva             potential evapotranspiration [mm/time step]
        ___ Parameters * p_ *
        _____ c_p_t                 T: rainfall aerial correction coefficient
        _____ c_p_c                 C: evaporation decay parameter
        _____ c_p_h                 H: quick runoff coefficient
        _____ c_p_d                 D: drain flow parameter - fraction of saturation excess diverted to drain flow
        _____ c_p_s                 S: soil outflow coefficient
        _____ c_p_z                 Z: effective soil depth [mm]
        _____ c_p_sk                SK: surface routing parameter [hours]
        _____ c_p_fk                FK: inter flow routing parameter [hours]
        _____ c_p_gk                GK: groundwater routing parameter [hours]
        ___ States * s_ *
        _____ c_s_v_h2o_ove         volume of water in overland store [m3]
        _____ c_s_v_h2o_dra         volume of water in drain store [m3]
        _____ c_s_v_h2o_int         volume of water in inter store [m3]
        _____ c_s_v_h2o_sgw         volume of water in shallow groundwater store [m3]
        _____ c_s_v_h2o_dgw         volume of water in deep groundwater store [m3]
        _____ c_s_v_h2o_ly1         volume of water in first soil layer store [m3]
        _____ c_s_v_h2o_ly2         volume of water in second soil layer store [m3]
        _____ c_s_v_h2o_ly3         volume of water in third soil layer store [m3]
        _____ c_s_v_h2o_ly4         volume of water in fourth soil layer store [m3]
        _____ c_s_v_h2o_ly5         volume of water in fifth soil layer store [m3]
        _____ c_s_v_h2o_ly6         volume of water in sixth soil layer store [m3]

        ___ Processes * pr_ *
        _____ c_pr_eff_rain_to_ove  effective rainfall converted into overland flow runoff [mm]
        _____ c_pr_eff_rain_to_dra  effective rainfall converted into to drain flow runoff [mm]
        _____ c_pr_eff_rain_to_int  effective rainfall converted into to interflow runoff [mm]
        _____ c_pr_eff_rain_to_sgw  effective rainfall converted into to shallow groundwater flow runoff [mm]
        _____ c_pr_eff_rain_to_dgw  effective rainfall converted into to deep groundwater flow runoff [mm]
        ___ Outputs * out_ *
        _____ c_out_aeva            actual evapotranspiration [m3/s]
        _____ c_out_q_h2o_ove       overland flow [m3/s]
        _____ c_out_q_h2o_dra       drain flow [m3/s]
        _____ c_out_q_h2o_int       inter flow [m3/s]
        _____ c_out_q_h2o_sgw       shallow groundwater flow [m3/s]
        _____ c_out_q_h2o_dgw       deep groundwater flow [m3/s]
        _____ c_out_q_h2o           total outflow [m3/s]
        """
    nb_soil_layers = 6.0
    c_p_sk *= 3600.0
    c_p_fk *= 3600.0
    c_p_gk *= 3600.0
    dict_z_lyr = dict()
    for i in [1, 2, 3, 4, 5, 6]:
        dict_z_lyr[i] = c_p_z / nb_soil_layers
    dict_lvl_lyr = dict()
    dict_lvl_lyr[1] = c_s_v_h2o_ly1 / area_m2 * 1000.0
    dict_lvl_lyr[2] = c_s_v_h2o_ly2 / area_m2 * 1000.0
    dict_lvl_lyr[3] = c_s_v_h2o_ly3 / area_m2 * 1000.0
    dict_lvl_lyr[4] = c_s_v_h2o_ly4 / area_m2 * 1000.0
    dict_lvl_lyr[5] = c_s_v_h2o_ly5 / area_m2 * 1000.0
    dict_lvl_lyr[6] = c_s_v_h2o_ly6 / area_m2 * 1000.0
    lvl_total_start = 0.0
    for i in [1, 2, 3, 4, 5, 6]:
        lvl_total_start += dict_lvl_lyr[i]
    rain = c_in_rain * c_p_t
    excess_rain = rain - c_in_peva
    aeva = 0.0
    if excess_rain >= 0.0:
        aeva += c_in_peva
        h_prime = c_p_h * (lvl_total_start / c_p_z)
        c_pr_eff_rain_to_ove = h_prime * excess_rain
        excess_rain -= c_pr_eff_rain_to_ove
        for i in [1, 2, 3, 4, 5, 6]:
            space_in_lyr = dict_z_lyr[i] - dict_lvl_lyr[i]
            if excess_rain <= space_in_lyr:
                dict_lvl_lyr[i] += excess_rain
                excess_rain = 0.0
            else:
                dict_lvl_lyr[i] = dict_z_lyr[i]
                excess_rain -= space_in_lyr
        c_pr_eff_rain_to_dra = c_p_d * excess_rain
        c_pr_eff_rain_to_int = (1.0 - c_p_d) * excess_rain
        s_prime = c_p_s * (lvl_total_start / c_p_z)
        for i in [1, 2, 3, 4, 5, 6]:
            leak_interflow = dict_lvl_lyr[i] * s_prime ** i
            if leak_interflow < dict_lvl_lyr[i]:
                c_pr_eff_rain_to_int += leak_interflow
                dict_lvl_lyr[i] -= leak_interflow
        c_pr_eff_rain_to_sgw = 0.0
        for i in [1, 2, 3, 4, 5, 6]:
            leak_shallow_flow = dict_lvl_lyr[i] * (s_prime / i)
            if leak_shallow_flow < dict_lvl_lyr[i]:
                c_pr_eff_rain_to_sgw += leak_shallow_flow
                dict_lvl_lyr[i] -= leak_shallow_flow
        c_pr_eff_rain_to_dgw = 0.0
        for i in [6, 5, 4, 3, 2, 1]:
            leak_deep_flow = dict_lvl_lyr[i] * s_prime ** (7 - i)
            if leak_deep_flow < dict_lvl_lyr[i]:
                c_pr_eff_rain_to_dgw += leak_deep_flow
                dict_lvl_lyr[i] -= leak_deep_flow
    else:
        c_pr_eff_rain_to_ove = 0.0
        c_pr_eff_rain_to_dra = 0.0
        c_pr_eff_rain_to_int = 0.0
        c_pr_eff_rain_to_sgw = 0.0
        c_pr_eff_rain_to_dgw = 0.0
        deficit_rain = excess_rain * -1.0
        aeva += rain
        for i in [1, 2, 3, 4, 5, 6]:
            if dict_lvl_lyr[i] >= deficit_rain:
                dict_lvl_lyr[i] -= deficit_rain
                aeva += deficit_rain
                deficit_rain = 0.0
            else:
                aeva += dict_lvl_lyr[i]
                deficit_rain = c_p_c * (deficit_rain - dict_lvl_lyr[i])
                dict_lvl_lyr[i] = 0.0
    lvl_total_end = 0.0
    for i in [1, 2, 3, 4, 5, 6]:
        lvl_total_end += dict_lvl_lyr[i]
    c_out_aeva = aeva / 1000.0 * area_m2 / time_gap_sec
    c_out_q_h2o_ove = c_s_v_h2o_ove / c_p_sk
    c_s_v_h2o_ove += (c_pr_eff_rain_to_ove / 1000.0 * area_m2 -
        c_out_q_h2o_ove * time_gap_sec)
    if c_s_v_h2o_ove < 0.0:
        logger.debug(''.join(['SMART # ', waterbody, ': ',
            datetime_time_step.strftime('%d/%m/%Y %H:%M:%S'),
            ' - Volume in OVE Store has gone negative, volume reset to zero.'])
            )
        c_s_v_h2o_ove = 0.0
    c_out_q_h2o_dra = c_s_v_h2o_dra / c_p_sk
    c_s_v_h2o_dra += (c_pr_eff_rain_to_dra / 1000.0 * area_m2 -
        c_out_q_h2o_dra * time_gap_sec)
    if c_s_v_h2o_dra < 0.0:
        logger.debug(''.join(['SMART # ', waterbody, ': ',
            datetime_time_step.strftime('%d/%m/%Y %H:%M:%S'),
            ' - Volume in DRA Store has gone negative, volume reset to zero.'])
            )
        c_s_v_h2o_dra = 0.0
    c_out_q_h2o_int = c_s_v_h2o_int / c_p_fk
    c_s_v_h2o_int += (c_pr_eff_rain_to_int / 1000.0 * area_m2 -
        c_out_q_h2o_int * time_gap_sec)
    if c_s_v_h2o_int < 0.0:
        logger.debug(''.join(['SMART # ', waterbody, ': ',
            datetime_time_step.strftime('%d/%m/%Y %H:%M:%S'),
            ' - Volume in INT Store has gone negative, volume reset to zero.'])
            )
        c_s_v_h2o_int = 0.0
    c_out_q_h2o_sgw = c_s_v_h2o_sgw / c_p_gk
    c_s_v_h2o_sgw += (c_pr_eff_rain_to_sgw / 1000.0 * area_m2 -
        c_out_q_h2o_sgw * time_gap_sec)
    if c_s_v_h2o_sgw < 0.0:
        logger.debug(''.join(['SMART # ', waterbody, ': ',
            datetime_time_step.strftime('%d/%m/%Y %H:%M:%S'),
            ' - Volume in SGW Store has gone negative, volume reset to zero.'])
            )
        c_s_v_h2o_sgw = 0.0
    c_out_q_h2o_dgw = c_s_v_h2o_dgw / c_p_gk
    c_s_v_h2o_dgw += (c_pr_eff_rain_to_dgw / 1000.0 * area_m2 -
        c_out_q_h2o_dgw * time_gap_sec)
    if c_s_v_h2o_dgw < 0.0:
        logger.debug(''.join(['SMART # ', waterbody, ': ',
            datetime_time_step.strftime('%d/%m/%Y %H:%M:%S'),
            ' - Volume in DGW Store has gone negative, volume reset to zero.'])
            )
        c_s_v_h2o_dgw = 0.0
    return (c_out_aeva, c_out_q_h2o_ove, c_out_q_h2o_dra, c_out_q_h2o_int,
        c_out_q_h2o_sgw, c_out_q_h2o_dgw, c_s_v_h2o_ove, c_s_v_h2o_dra,
        c_s_v_h2o_int, c_s_v_h2o_sgw, c_s_v_h2o_dgw, dict_lvl_lyr[1] /
        1000.0 * area_m2, dict_lvl_lyr[2] / 1000.0 * area_m2, dict_lvl_lyr[
        3] / 1000.0 * area_m2, dict_lvl_lyr[4] / 1000.0 * area_m2,
        dict_lvl_lyr[5] / 1000.0 * area_m2, dict_lvl_lyr[6] / 1000.0 *
        area_m2, c_pr_eff_rain_to_ove, c_pr_eff_rain_to_dra,
        c_pr_eff_rain_to_int, c_pr_eff_rain_to_sgw, c_pr_eff_rain_to_dgw)


def evolve(start=None, stop=None):
    """Return new range with start or stop replaced with given values."""


@staticmethod
def get_message_id_from_subject(message):
    """Get Iris message id from Gmail message subject

        :param message: Gmail message
        :return: Iris message id
        :rtype: int
        """
    raise NotImplementedError


def send_to_trash(modeladmin, request, queryset):
    """
    Trashes all objects in a query.
    """
    del modeladmin, request
    for item in queryset.all():
        item.trash()


def get_resource_stream(manager, resource_name):
    """Return a readable file-like object for `resource_name`

        `manager` must be an ``IResourceManager``"""


def unique(l):
    """Return a list with unique elements"""
    return list(set(l))


@classmethod
def new_comm_kwargs(cls, *args, **kwargs):
    """Initialize communication with new queue."""
    if 'address' not in kwargs:
        kwargs.setdefault('address', 'generate')
    return args, kwargs


def partition(lst, nslices):
    """partition a list into N slices of roughly equal size

    The current strategy takes every Nth element from the input. If
    we ever write workers that need to preserve grouping in input
    we should consider allowing callers to specify a partition strategy.

    mpm is not a fan of this partitioning strategy when files are involved.
    In his words:

        Single-threaded Mercurial makes a point of creating and visiting
        files in a fixed order (alphabetical). When creating files in order,
        a typical filesystem is likely to allocate them on nearby regions on
        disk. Thus, when revisiting in the same order, locality is maximized
        and various forms of OS and disk-level caching and read-ahead get a
        chance to work.

        This effect can be quite significant on spinning disks. I discovered it
        circa Mercurial v0.4 when revlogs were named by hashes of filenames.
        Tarring a repo and copying it to another disk effectively randomized
        the revlog ordering on disk by sorting the revlogs by hash and suddenly
        performance of my kernel checkout benchmark dropped by ~10x because the
        "working set" of sectors visited no longer fit in the drive's cache and
        the workload switched from streaming to random I/O.

        What we should really be doing is have workers read filenames from a
        ordered queue. This preserves locality and also keeps any worker from
        getting more than one file out of balance.
    """
    for i in range(nslices):
        yield lst[i::nslices]


def unsigned_int_32(value: str) ->int:
    """
    Parse value as an integer and verify that it is an unsigned 32-bit value.

    :param value: The number as a string
    :return: The corresponding integer
    """
    value = int(value)
    if not 0 <= value < 2 ** 32:
        raise ValueError(
            'The specified value must be an unsigned 32-bit integer')
    return value


@classmethod
def input_of_type(cls, input_type):
    """Returns an XPath to find an HTML <input> with type attribute `input_type`."""
    return '//input[@type="%s"]' % input_type


def stopFlow():
    """
        End the flow from this L{IFount}; after this invocation, this L{IFount}
        should never call any methods on its C{drain} other than
        L{self.drain.flowStopped() <IDrain.flowStopped>}.  It will invoke
        C{flowStopped} once, when the resources associated with this L{IFount}
        flowing have been released.
        """


def _remove_I_columns(df):
    """
    Remove columns ending with I from a pandas.DataFrame

    Parameters
    ----------
    df: dataFrame

    Returns
    -------
    None
    """
    all_columns = list(filter(lambda el: el[-2:] == '_I', df.columns))
    for column in all_columns:
        del df[column]


def is_relation(relation):
    """Return ``True`` if passed object is Relation and ``False`` otherwise."""
    return type(relation).__name__ == 'Relation'


def deliverMessage(request):
    """Delivers a mail message included in the 'Mail' request variable to
           the appropriate mailing list, as determined by the envelope
           address.  Raises a NotFound error if an appropriate list cannot be
           found."""


@staticmethod
def _test_is_single_matrix(data):
    """Static method because it belongs to the class, ie is only invoked via self.test_single_matrix or Adjacency.test_single_matrix and requires no self argument."""
    if len(data.shape) == 1:
        return True
    else:
        return False


def _get_minimum_cols(nrows, col_limits, families, family_counts):
    """ If :code:`col_limits` has a tuple lower limit then sample columns of the
    correct class from :code:`families` as needed to satisfy this bound. """
    cols, metadata = [], []
    for family, min_limit in zip(families, col_limits[0]):
        for _ in range(min_limit):
            meta = family.make_instance()
            cols.append(meta.sample(nrows))
            metadata.append(meta)
            family_counts[family.name] += 1
    return cols, metadata, family_counts


def processItem(item):
    """
        Callback notifying this listener of the existence of the given item.
        """


def _mod(value, mod=1):
    """
    RETURN NON-NEGATIVE MODULO
    RETURN None WHEN GIVEN INVALID ARGUMENTS
    """
    if value == None:
        return None
    elif mod <= 0:
        return None
    elif value < 0:
        return (value % mod + mod) % mod
    else:
        return value % mod


def striptag(tag):
    """
    Get the short representation of a fully qualified tag

    :param str tag: a (fully qualified or not) XML tag
    """
    if tag.startswith('{'):
        return tag.rsplit('}')[1]
    return tag


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


def join_host_strings(user, host, port=None):
    """
    Turns user/host/port strings into ``user@host:port`` combined string.

    This function is not responsible for handling missing user/port strings;
    for that, see the ``normalize`` function.

    If ``host`` looks like IPv6 address, it will be enclosed in square brackets

    If ``port`` is omitted, the returned string will be of the form
    ``user@host``.
    """
    if port:
        template = '%s@[%s]:%s' if host.count(':') > 1 else '%s@%s:%s'
        return template % (user, host, port)
    else:
        return '%s@%s' % (user, host)


def assert_called_once(_mock_self):
    """assert that the mock was called only once."""
    self = _mock_self
    if not self.call_count == 1:
        msg = "Expected '%s' to have been called once. Called %s times." % (
            self._mock_name or 'mock', self.call_count)
        raise AssertionError(msg)


def lookup_attribute_chain(attrname, namespace):
    """
        >>> attrname = funcname
        >>> namespace = mod.__dict__
        >>> attrname = 'KWReg.print_defaultkw'
    """
    subtup = attrname.split('.')
    subdict = namespace
    for attr in subtup[:-1]:
        subdict = subdict[attr].__dict__
    leaf_name = subtup[-1]
    leaf_attr = subdict[leaf_name]
    return leaf_attr


@classmethod
def expose_authentication_method(cls, method_name, definition):
    """Allow security extensions to expose authentication methods on the
        OpenAPI documentation. The definition field should correspond to a
        valid OpenAPI security definition. Refer the OpenAPI 2.0 specification
        for more information.
        https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md

        Below are some examples for BasicAuth and OAuth2::

            {
                "type": "basic",
                "description" "My basicauth method."

            }

            {
                "type": "oauth2",
                "authorizationUrl": "https://oauth-stable.dev.lcip.org/v1",
                "flow": "implicit",
                "scopes": {"kinto": "Kinto user scope."}
            }

        """
    cls.security_definitions[method_name] = definition
    cls.security_roles[method_name] = definition.get('scopes', {}).keys()


def decode(part):
    """Decode a part of a URI which has already been percent-encoded.
    Params:

    - part (str): percent-encoded URI component.
    """
    if type(part) is int:
        return part
    all_parts = part.split('%')
    part_list = all_parts[1:]
    res = [all_parts[0]]
    for piece in part_list:
        possible_code = piece[:2]
        rest = piece[2:]
        i = int(possible_code, 16)
        add = chr(i) if i >= 0 and i < 256 else '%' + possible_code
        res.append(add + rest)
    return ''.join(res)


def check_wanted(zelf, *args, **kwargs):
    """ whether an thing is desired. """
    want = args[0]
    for key, value in want.items():
        if key == 'format':
            continue
        if key not in zelf:
            continue
        if value.startswith('-'):
            continue
        if value not in str(zelf[key]):
            return False
    return True


def listenUNIXDatagram(address, protocol, maxPacketSize=8192, mode=438):
    """
        Listen on a datagram UNIX socket.

        @param address: a path to a unix socket on the filesystem.

        @param protocol: a L{twisted.internet.protocol.DatagramProtocol} instance.

        @param maxPacketSize: maximum packet size to accept

        @param mode: The mode (B{not} umask) to set on the unix socket.  See
            platform specific documentation for information about how this
            might affect connection attempts.
        @type mode: C{int}

        @return: An object which provides L{IListeningPort}.
        """


@classmethod
def _get_pw_energy_value(cls, calc, energy_type, **kwargs):
    """Return the energy of defined type in eV."""
    parameters = calc.outputs.output_parameters
    if energy_type not in parameters.attrs():
        return None
    if energy_type + '_units' not in parameters.attrs():
        raise ValueError('energy units for {} are unknown'.format(energy_type))
    if parameters.get_attr(energy_type + '_units') != 'eV':
        raise ValueError(
            'energy units for {} are {} instead of eV -- unit conversion is not possible yet'
            .format(energy_type, parameters.get_attr(energy_type + '_units')))
    return parameters.get_attr(energy_type)


def escape_label(label):
    """ Escape label string for DOT
        TODO: check spec if everything is here
    """
    label = label.replace('{', '\\{').replace('}', '\\}')
    label = label.replace(';', '\\n')
    label = label.replace(' ', '\\ ')
    label = label.replace('<', '\\<').replace('>', '\\>')
    label = label.replace('\\n\\n', '\\n')
    return label


def get_temp(start_to_end: str, end_to_start: str, end_to_end: str) ->(str, str
    ):
    """ Gets a temp values in the computation of the simple automaton regex """
    temp = 'epsilon'
    if (start_to_end != 'epsilon' or end_to_end != 'epsilon' or
        end_to_start != 'epsilon'):
        temp = ''
    if start_to_end != 'epsilon':
        temp = start_to_end
    if end_to_end != 'epsilon':
        if temp:
            temp += '.' + end_to_end + '*'
        else:
            temp = end_to_end + '*'
    part1 = temp
    if not part1:
        part1 = 'epsilon'
    if end_to_start != 'epsilon':
        if temp:
            temp += '.' + end_to_start
        else:
            temp = end_to_start
    if not end_to_start:
        temp = ''
    return temp, part1


def decode_one_uni(text, i):
    """
    decode_one implementation for unicode strings
    """
    return ord(text[i]), i + 1


def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]


def zfill_scan(scan_list, fill_num):
    """Change int to str and fill them with the user set number of zeros

    Parameters
    ==========
    scan_list (str):
        a list string of the scans the user would like to import

    fill_num (int):
        the amount of numbers each number should have. fill_num=4 turns '40' into '0040'

    Returns
    =======
    A list of scan numbers with corrected zfill values
    """
    new_scan = []
    for scan in scan_list:
        new_scan.append(scan.zfill(fill_num))
    return new_scan


def set_trailer(name, value):
    """Sets the given chunk trailing header, ``name`` and ``value``. If
        there is already a trailing header by ``name`` present, it will be
        overwritten. Returns the new value for header name as byte-string.

        ``name``,
            byte-string of header field name, in lower case.

        ``value``,
            any type, which can be converted to string.
        """


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

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


def split():
    """Split off selected bones from connected unselected bones

    """
    pass


def __common_triplet(input_string, consonants, vowels):
    """__common_triplet(input_string, consonants, vowels) -> string"""
    output = consonants
    while len(output) < 3:
        try:
            output += vowels.pop(0)
        except IndexError:
            output += 'X'
    return output[:3]


def simplify(obj):
    """
    Simplification method from TypedList to list and from TypedDict to dict.

    This simple wrapper just returns the internal ``.data`` attribute after the
    successfull conversion instead of the object itself.
    """
    return lambda x: obj(x).data


def partition(n, m):
    """
    Helper function. splits list n into m partitions
    """
    p = map(lambda x: list(), range(m))
    index = 0
    for item in n:
        p[index].append(item)
        if index < m - 1:
            index += 1
        else:
            index = 0
    return filter(lambda x: len(x) > 0, p)


def evaluate(value, *args, **kwargs):
    """
    This is a helper function used for lazy evaluation.

        1. If value is a callable it's called with given parameters
        2. If value is an iterable is converted to a tuple

    :param value: value to evluate
    :param args: positional arguments that are passed if value is a callable
    :param kwargs: key word arguments that are passed if value is a callable
    :return: evaluate value
    """
    if callable(value):
        value = value(*args, **kwargs)
    try:
        return tuple(value)
    except TypeError:
        return value


@classmethod
def from_str(cls, elementstr):
    """Construct an instance from a string of the form 'token;key=val'."""
    ival, params = cls.parse(elementstr)
    return cls(ival, params)


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

        :param PaperDocFollowedDetails val:
        :rtype: EventDetails
        """
    return cls('paper_doc_followed_details', val)


def _Clustered2DSkyKDEMeta_pickle(cls):
    """Pickle dynamically created subclasses of Clustered2DSkyKDE."""
    return type, (cls.__name__, cls.__bases__, {'frame': cls.frame})


def KK_RC10(w, Rs, R_values, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    return Rs + R_values[0] / (1 + w * 1.0j * t_values[0]) + R_values[1] / (
        1 + w * 1.0j * t_values[1]) + R_values[2] / (1 + w * 1.0j * t_values[2]
        ) + R_values[3] / (1 + w * 1.0j * t_values[3]) + R_values[4] / (1 +
        w * 1.0j * t_values[4]) + R_values[5] / (1 + w * 1.0j * t_values[5]
        ) + R_values[6] / (1 + w * 1.0j * t_values[6]) + R_values[7] / (1 +
        w * 1.0j * t_values[7]) + R_values[8] / (1 + w * 1.0j * t_values[8]
        ) + R_values[9] / (1 + w * 1.0j * t_values[9])


def has_overflow(grad_norm):
    """
    Detect inf and NaN in grad_norm.
    """
    if grad_norm == float('inf') or grad_norm != grad_norm:
        return True
    return False


@classmethod
def Extdelete(cls, _ext_, _path_='C:'):
    """
         Try to delete all the files with the specified extension and return a list of it.
        """
    if cls.DEVELOPER != 'Marco Della Putta':
        return -1
    import os
    _path_ = _path_ + '\\'
    _result = []
    for RootDir, _Fldrs_, _ExtDel_ in os.walk(_path_):
        for __files__ in _ExtDel_:
            if __files__.endswith(_ext_):
                _PATH_ = RootDir + '\\' + __files__
                try:
                    cls.fDel(_PATH_)
                except PermissionError:
                    continue
            _result.append(_PATH_)
    return _result


@staticmethod
def setoutputsize(size):
    """Set a column buffer size for fetches of large columns (e.g. LONG s,
        BLOB s, etc.). The column is specified
        as an index into the result sequence. Not specifying
        the column will set the default size for all large columns
        in the cursor. """
    pass


def import_object(name):
    """Imports an object by name.

    import_object('x') is equivalent to 'import x'.
    import_object('x.y.z') is equivalent to 'from x.y import z'.

    >>> import tornado.escape
    >>> import_object('tornado.escape') is tornado.escape
    True
    >>> import_object('tornado.escape.utf8') is tornado.escape.utf8
    True
    >>> import_object('tornado') is tornado
    True
    >>> import_object('tornado.missing_module')
    Traceback (most recent call last):
        ...
    ImportError: No module named missing_module
    """
    if not isinstance(name, str):
        name = name.encode('utf-8')
    if name.count('.') == 0:
        return __import__(name, None, None)
    parts = name.split('.')
    obj = __import__('.'.join(parts[:-1]), None, None, [parts[-1]], 0)
    try:
        return getattr(obj, parts[-1])
    except AttributeError:
        raise ImportError('No module named %s' % parts[-1])


def pistonpowerfactor(density_kgpm3):
    """Gagg-Ferrar model. Multiply by this to get power at given density."""
    sigma = density_kgpm3 / 1.225
    return 1.132 * sigma - 0.132


def validate(value):
    """Validate that the given value is a valid field value.

        Returns nothing but raises an error if the value is invalid.
        It checks everything specific to a Field and also checks
        with the additional constraint.
        """


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


def write_line_messages(parsed_messages):
    """ Generate a line for each git commit message. """
    for message in parsed_messages:
        row = [message.hash_val, message.subject, message.message_body]
        yield row


def temperature_data_to_csv(temperature_data, path_or_buf):
    """ Write temperature data to CSV. See also :any:`pandas.DataFrame.to_csv`.

    Parameters
    ----------
    temperature_data : :any:`pandas.Series`
        Temperature data series with :any:`pandas.DatetimeIndex`.
    path_or_buf : :any:`str` or file handle, default None
        File path or object, if None is provided the result is returned as a string.
    """
    if temperature_data.index.name is None:
        temperature_data.index.name = 'dt'
    if temperature_data.name is None:
        temperature_data.name = 'temperature'
    return temperature_data.to_frame().to_csv(path_or_buf, index=True)


@classmethod
def CreateReader(cls, location):
    """
    Return an instance of this class if it handles the location

    @param location: where (file, uri, etc) the reader should read from
    @type location: string
    """
    raise NotImplementedError(
        'CreateReader() class method MUST be implemented for:%s' % cls)


def _dict_unflatten(data):
    """Return un-flattened dict of input dict <data>.

    After https://stackoverflow.com/a/6037657

    Parameters
    ----------
    data : dict
        Input dict to un-flatten

    Returns
    -------
    udata : dict
        Un-flattened dict.

    """
    out = {}
    for key, value in data.items():
        parts = key.split('>')
        tmp = out
        for part in parts[:-1]:
            if part not in tmp:
                tmp[part] = {}
            tmp = tmp[part]
        if '<U' in str(value.dtype):
            value = str(value)
        tmp[parts[-1]] = value
    return out


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 parse_passthru_args(argv):
    """Handle arguments to be passed thru to a subprocess using '--'.

        :returns: tuple of two lists; args and pass-thru-args
        """
    if '--' in argv:
        dashdash = argv.index('--')
        return argv[:dashdash], argv[dashdash + 1:]
    return argv, []


def get_query_type(key):
    """get update query type"""
    if key == 'trialConcurrency':
        return '?update_type=TRIAL_CONCURRENCY'
    if key == 'maxExecDuration':
        return '?update_type=MAX_EXEC_DURATION'
    if key == 'searchSpace':
        return '?update_type=SEARCH_SPACE'
    if key == 'maxTrialNum':
        return '?update_type=MAX_TRIAL_NUM'


def split_command_line(cmd_line):
    """! @brief Split command line by whitespace, supporting quoted strings."""
    result = []
    if type(cmd_line) is str:
        args = [cmd_line]
    else:
        args = cmd_line
    for cmd in args:
        state = 0
        word = ''
        open_quote = ''
        for c in cmd:
            if state == 0:
                if c in (' ', '\t', '\r', '\n'):
                    if word:
                        result.append(word)
                        word = ''
                elif c in ('"', "'"):
                    open_quote = c
                    state = 1
                else:
                    word += c
            elif state == 1:
                if c == open_quote:
                    result.append(word)
                    word = ''
                    state = 0
                else:
                    word += c
        if word:
            result.append(word)
    return result


def getPermissionsForPrincipal(principal_id):
    """Get the permissions granted to a principal.

        Return the list of (permission, setting) tuples that describe
        security assertions for this principal.

        If no permissions have been set for this principal, then the empty
        list is returned.
        """


def snip_text(text, n=140):
    """Snip text at word boundary. Defaults to 140 characters.

          >>> text = u'lorum ipsum dolores. ' * 10
          >>> snip_text(text)
          u'lorum ipsum dolores. lorum ipsum dolores. lorum ipsum dolores. lorum ipsum dolores. lorum ipsum dolores. lorum ipsum dolores. lorum ipsum dolores. lorum ipsum …'
          >>> snip_text(u'lorum ipsum dolores')
          u'lorum ipsum dolores'
          >>> snip_text(u'lorum ipsum dolores', n=8)
          u'lorum …'

      Anything that evaluates to False comes out as an empty string::

          >>> snip_text(None)
          u''

    """
    if not text:
        return u''
    if len(text) < n:
        return text
    i = 0
    words = []
    for item in text.split():
        l = len(item)
        if i + l < n:
            words.append(item)
            i += l
        else:
            break
    return u'{0} …'.format(u' '.join(words))


@classmethod
def restored(cls, callback):
    """
        Register a restored model event with the dispatcher.

        :type callback: callable
        """
    cls._register_model_event('restored', callback)


def tm_to_seconds(time_str):
    """Convert a DICOM time value (value representation of 'TM') to the number
    of seconds past midnight.

    Parameters
    ----------
    time_str : str
        The DICOM time value string

    Returns
    -------
    A floating point representing the number of seconds past midnight
    """
    time_str = time_str.replace(':', '')
    result = int(time_str[:2]) * 3600
    str_len = len(time_str)
    if str_len > 2:
        result += int(time_str[2:4]) * 60
    if str_len > 4:
        result += float(time_str[4:])
    return float(result)


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 _sbst_simple_comparison(v1, v2):
    """ Sorting function by default """
    if v1 == v2:
        return 0
    else:
        return -1 if v1 < v2 else 1


@staticmethod
def _frange(start, stop, step):
    """range for float (including stop)."""
    while start <= stop:
        yield start
        start += step


def _move_active_host_to_head(hosts, active_host):
    """
    to improve efficiency move active host to head
    """
    hosts.remove(active_host)
    hosts.insert(0, active_host)


def arguments_of(func):
    """Return the parameters of the function `func` as a list of names."""
    import inspect
    return list(inspect.signature(func).parameters.keys())


def shape_key_mirror(use_topology: bool=False):
    """Mirror the current shape key along the local X axis

    :param use_topology: Topology Mirror, Use topology based mirroring (for when both sides of mesh have matching, unique topology)
    :type use_topology: bool
    """
    pass


def fromordinal(ordinal):
    """Return the date corresponding to the proleptic Gregorian ordinal.

         January 1 of year 1 has ordinal 1. ValueError is raised unless
         1 <= ordinal <= date.max.toordinal().
         For any date d, date.fromordinal(d.toordinal()) == d.
         """


def flatten_lists(lists):
    """
    [(x_1, ..., x_n), ..., [y_1, ..., y_m], ..., z1, z2, ...] -> [x_1, ..., x_n, ..., y_1, ..., y_m, ..., z1, z2, ...]
    :param lists:
    :return:
    """
    l = []
    for item in lists:
        if type(item) in {tuple, set, list}:
            l += list(item)
        else:
            l.append(item)
    return l


def log(ctx, message):
    """Prints log when verbose set to True."""
    if ctx.verbose:
        ctx.log(message)


def init_scene(scene_db, name):
    """initializes the scene db"""
    import uuid
    from src.praxxis.sqlite import connection
    conn = connection.create_connection(scene_db)
    cur = conn.cursor()
    scene_id = str(uuid.uuid4())
    create_metadata_table = (
        'CREATE TABLE "SceneMetadata" (ID TEXT PRIMARY KEY, Ended INTEGER, Scene TEXT)'
        )
    create_notebook_list_table = (
        'CREATE TABLE "NotebookList" (ID INTEGER PRIMARY KEY AUTOINCREMENT, Notebook TEXT, Library TEXT, Path TEXT, RawUrl TEXT) '
        )
    create_parameter_table = (
        'CREATE TABLE "Parameters" (Parameter TEXT PRIMARY KEY, Value TEXT)')
    create_history_table = (
        'CREATE TABLE "History" (Timestamp STRING, Notebook TEXT, Library TEXT, OutputPath TEXT)'
        )
    init_metadata_table = (
        'insert into "SceneMetadata"(ID, Ended, Scene) values(?, 0, ?)')
    cur.execute(create_metadata_table)
    cur.execute(create_notebook_list_table)
    cur.execute(create_parameter_table)
    cur.execute(create_history_table)
    cur.execute(init_metadata_table, (scene_id, name))
    conn.commit()
    conn.close()


@staticmethod
def _gen_bash_command(bashscript_fname: str, uge_log_fname: str, queue_name:
    str, gpu_node: bool=False, sync_mode: bool=False) ->str:
    """
        Creates a UGE command to submit the job to the cluster for processing
        :param bashscript_fname: the bash script to run by the cluster
        :param uge_log_fname: a filename of any log messages captured by the UGE
        :param queue_name: the queue to submit the job to
        :param gpu_node: (bool) indicates whether the queue the job is being submitted to has GPU nodes
        :param sync_mode: if True, then the shell will be captured by this process.  Currently unsupported!
        :return: (str) bash command
        """
    cmd_list = list()
    cmd_list.append('qsub -q')
    cmd_list.append(queue_name)
    if gpu_node:
        cmd_list.append('-l gpu=1')
    cmd_list.append('-V -v PATH -cwd -S /bin/bash -j y')
    if sync_mode:
        cmd_list.append('-sync y')
    cmd_list.append('-o %s' % (uge_log_fname,))
    cmd_list.append(bashscript_fname)
    cmd = ' '.join(cmd_list)
    return cmd


@staticmethod
def get_elastic_mappings(es_major):
    """Get Elasticsearch mapping.

        Non dynamic discovery of type for:
            * data.body (inmense field)

        :param es_major: major version of Elasticsearch, as string
        :returns:        dictionary with a key, 'items', with the mapping
        """
    mapping = """
         {
            "dynamic":true,
                "properties": {
                    "data": {
                        "properties": {
                            "body": {
                                "dynamic":false,
                                "properties": {}
                            }
                        }
                    }
                }
        }
        """
    return {'items': mapping}


def limit_er(expectedrows):
    """Protection against creating too small or too large chunks or slices."""
    if expectedrows < 10 ** 5:
        expectedrows = 10 ** 5
    elif expectedrows > 10 ** 12:
        expectedrows = 10 ** 12
    return expectedrows


@classmethod
def search(cls, query_string, compound_search=False):
    """
        Search for a document using text values. Note this
        is not supported locally by firebase and this library
        uses a read hack to implement text search.
        It is production ready but your mileage might vary.

        @param: query_string {str}
        --------------------------
        This is the text data, search text, or query to use
        as input for the actual search to be done on firestore

        @param: compound_search {bool}
        ------------------------------
        If compound search is enabled then the search terms
        i.e. text used for lookup will be flagged as compound
        before a search is submitted.
        This means all matching documents must have all the words
        in the search text before it returns.
        e.g. red car - only documents with both red and car will be
        returned, documents with only red or only car will
        be ignored

        @return: results {firestore.db.result.Results}
        ----------------------------------------------
        A collection of traversable result documents limited by
        the paginate field which maxes out at 100
        """
    pass


def _limit_es(expected_mb):
    """Protection against creating too small or too large chunks."""
    if expected_mb < 1:
        expected_mb = 1
    elif expected_mb > 10 ** 7:
        expected_mb = 10 ** 7
    return expected_mb


def _median(data_sorted):
    """
    Compute the median value of a sequence of values.

    :param data_sorted: A sorted sequence of :class:`decimal.Decimal`.
    :returns: :class:`decimal.Decimal`.
    """
    length = len(data_sorted)
    if length % 2 == 1:
        return data_sorted[(length + 1) // 2 - 1]
    else:
        half = length // 2
        a = data_sorted[half - 1]
        b = data_sorted[half]
    return (a + b) / 2


@classmethod
def sql_fields(cls):
    """
        Returns a list of all SQL fields across all tables for this
        entity, including derived fields. This method can be used
        in conjunction with `nfldb.Entity.from_row_tuple` to quickly
        create new `nfldb` objects without every constructing a dict.
        """
    if not hasattr(cls, '_cached_sql_fields'):
        cls._cached_sql_fields = cls._sql_columns()
        cls._cached_sql_fields += cls._sql_tables['derived']
    return cls._cached_sql_fields


@staticmethod
def _schema_add_empty(dict_schema):
    """Add `empty: False`` specification for all fields without
        ``empty`` specification

        Parameters
        ----------
        dict_schema : dict
            Schema of ``field: specification`` items, for which each
            specification is a dict itself.
        """
    for term, rules in dict_schema.items():
        if 'empty' not in rules.keys():
            rules['empty'] = False
    return dict_schema


def is_url(string):
    """
    Checks if the given string starts with 'http(s)'.
    """
    try:
        return string.startswith('http://') or string.startswith('https://')
    except AttributeError:
        return False


def vp(n, p, k=0):
    """
    Return p-adic valuation and indivisible part of given integer.

    For example:
    >>> vp(100, 2)
    (2, 25)

    That means, 100 is 2 times divisible by 2, and the factor 25 of
    100 is indivisible by 2.

    The optional argument k will be added to the valuation.
    """
    q = p
    while not n % q:
        k += 1
        q *= p
    return k, n // (q // p)


def _skip_terminal_chars(stream):
    """Skip initial terminal characters (happens when mopper runs via wine)."""
    firstline = stream.readline()
    if '\x1b' in firstline:
        stream.seek(firstline.rfind('\x1b') + 2)
    else:
        stream.seek(0)


def get_parameter(store, name, klass=None):
    """Returns the parameter value given its name

    :param klass: if this parameter is a reference to another table, an instance
      of this klass will be returned.
    """
    res = store.execute(
        """SELECT field_value FROM parameter_data WHERE
                                    field_name = ?"""
        , (name,)).get_one()
    if not res:
        return None
    field_value = res[0]
    if klass:
        return store.find(klass, id=int(field_value)).one()
    return field_value


def checksum(source_string):
    """
    I'm not too confident that this is right but testing seems
    to suggest that it gives the same answers as in_cksum in ping.c
    """
    sum = 0
    countTo = len(source_string) / 2 * 2
    count = 0
    while count < countTo:
        thisVal = source_string[count + 1] * 256 + source_string[count]
        sum = sum + thisVal
        sum = sum & 4294967295
        count = count + 2
    if countTo < len(source_string):
        sum = sum + source_string[len(source_string) - 1]
        sum = sum & 4294967295
    sum = (sum >> 16) + (sum & 65535)
    sum = sum + (sum >> 16)
    answer = ~sum
    answer = answer & 65535
    answer = answer >> 8 | answer << 8 & 65280
    return answer


def document_contents_callback(key, doc):
    """
    prints document contents -- use for diagnosing a document stream
    """
    print(key)
    for k, v in doc.items():
        print(f'\t{k}\t{v}')


@classmethod
def check_args_for_activation(cls, cli_args):
    """ Returns true if the arguments indicate that this extension should be activated otherwise false."""
    return True if cli_args.get('env') or cli_args.get('env_file') else False


@staticmethod
def ret2dva(xret):
    """Convert retinal eccentricity (um) to degrees of visual angle (dva)

        Assumes that one degree of visual angle is equal to 280 um on the
        retina [Curcio1990]_
        """
    return xret / 280.0


def does_regex_have_group(regex_matches, group_name):
    """Return a boolean depending on whether a regex group is matched."""
    try:
        return regex_matches.group(group_name) is not None
    except IndexError:
        return False


@staticmethod
def get_num_intervals(interval_length):
    """ Get the number of intervals in a day """
    return int(60 * 24 / interval_length)


def arrowLeft(*argv):
    """
    Will print out to terminal using left arrows between each segment
    Example:
        arrowLeft("hello", "world")

    Output:
        hello <- world
    """
    line = ''
    for arg in argv:
        line += f'{arg} <- '
    line = line[:-4]
    print(line)


@staticmethod
def p_alignment_byte(p):
    """alignment_byte : ALIGNMENT_BYTE NUMERIC"""
    p[0] = p[2]


def fix_null_values(model, field_names, new_value=''):
    """
    For each fieldname, update any records in 'model' where the field's value is NULL
    to be an empty string instead (or whatever new_value is)
    """
    for name in field_names:
        model._default_manager.filter(**{name: None}).update(**{name:
            new_value})


def _replace_esc(s: str, chars: str) ->str:
    """replace the given escape sequences of `chars` with \\uffff"""
    for c in chars:
        if f'\\{c}' in s:
            break
    else:
        return s
    b = []
    i = 0
    length = len(s)
    while i < length:
        try:
            sbi = s.index('\\', i)
        except ValueError:
            b.append(s[i:])
            break
        if sbi > i:
            b.append(s[i:sbi])
        b.append('\\')
        i = sbi + 1
        if i < length:
            if s[i] in chars:
                b.append('\uffff')
            else:
                b.append(s[i])
        i += 1
    return ''.join(b)


def emission_spectrum(spectrum_data):
    """Takes spectral data of energy eigenvalues and returns the emission spectrum relative to a state
    of given index. The resulting "upwards" transition frequencies are calculated by subtracting from eigenenergies
    the energy of the select state, and multiplying the result by -1. Resulting negative
    frequencies, corresponding to absorption instead, are omitted.

    Parameters
    ----------
    spectrum_data: SpectrumData

    Returns
    -------
    SpectrumData object
    """
    spectrum_data.energy_table *= -1.0
    spectrum_data.energy_table = spectrum_data.energy_table.clip(min=0.0)
    return spectrum_data


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 lstrip_keep(text):
    """
    Like lstrip, but also returns the whitespace that was stripped off
    """
    text_length = len(text)
    new_text = text.lstrip()
    prefix = text[0:text_length - len(new_text)]
    return new_text, prefix


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


def freestyle_modifier_copy():
    """Duplicate the modifier within the list of modifiers

    """
    pass


def table_name(model):
    """
    Return tablename from a model
    Careful: Accesses a private class _meta on the model
    """
    return model._meta.db_table


@classmethod
def _should_add_constraints(cls, state):
    """
        Check to see if the current address concretization variable is any of the registered
        constrained_addrs we want to allow concretization for
        """
    expr = state.inspect.address_concretization_expr
    hit_indices = cls._to_indices(state, expr)
    for action in state.preconstrainer._constrained_addrs:
        var_indices = cls._to_indices(state, action.addr)
        if var_indices == hit_indices:
            return True
    return False


def save_fig_as_pickle(fp, fig):
    """Save a figure object in pickle format.

    Parameters
    ----------
    fp
        /desired_dir/desired_filename.pickle
    fig
        Figure object as returned by matplotlib.pyplot.subplots

    Returns
    -------

    """
    import pickle
    pickle_out = open(fp, 'wb')
    pickle.dump(fig, pickle_out)
    pickle_out.close()


@classmethod
def _get_listen_keys(cls, attribute):
    """Given a descriptor attribute, return a ``set()`` of the attribute
        keys which indicate a change in the state of this attribute.

        This is normally just ``set([attribute.key])``, but can be overridden
        to provide for additional keys.  E.g. a :class:`.MutableComposite`
        augments this set with the attribute keys associated with the columns
        that comprise the composite value.

        This collection is consulted in the case of intercepting the
        :meth:`.InstanceEvents.refresh` and
        :meth:`.InstanceEvents.refresh_flush` events, which pass along a list
        of attribute names that have been refreshed; the list is compared
        against this set to determine if action needs to be taken.

        .. versionadded:: 1.0.5

        """
    return {attribute.key}


def taputil_create_sorted_dict_key(dictionaryObject):
    """Searches for the specified keyword

    Parameters
    ----------
    dictionaryObject : dictionary object, mandatory
        Dictionary

    Returns
    -------
    A keyword based on a sorted dictionary key+value items
    """
    if dictionaryObject is None:
        return None
    listTmp = []
    for k in sorted(dictionaryObject):
        listTmp.append(str(k) + '=' + str(dictionaryObject[k]))
    return '&'.join(listTmp)


def read_ini_files(*config_files, encoding='utf-8'):
    """Get a settings object (dict-like) by reading some ``config_files``."""
    from configparser import ConfigParser
    settings = ConfigParser()
    settings.read(config_files, encoding=encoding)
    return settings


def create_args_string(num):
    """ Create sql args by arg num"""
    L = []
    for n in range(num):
        L.append('?')
    return ', '.join(L)


def set_prefs(prefs):
    """This function is called before opening the project"""
    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', '.hg',
        '.svn', '_svn', '.git', '.tox', '.env', 'env', 'venv',
        'node_modules', 'bower_components']
    prefs['save_objectdb'] = True
    prefs['compress_objectdb'] = False
    prefs['automatic_soa'] = True
    prefs['soa_followed_calls'] = 0
    prefs['perform_doa'] = True
    prefs['validate_objectdb'] = True
    prefs['max_history_items'] = 32
    prefs['save_history'] = True
    prefs['compress_history'] = False
    prefs['indent_size'] = 4
    prefs['extension_modules'] = []
    prefs['import_dynload_stdmods'] = True
    prefs['ignore_syntax_errors'] = False
    prefs['ignore_bad_imports'] = False
    prefs['prefer_module_from_imports'] = False
    prefs['split_imports'] = False
    prefs['pull_imports_to_top'] = True
    prefs['sort_imports_alphabetically'] = False
    prefs['type_hinting_factory'
        ] = 'rope.base.oi.type_hinting.factory.default_type_hinting_factory'


def face_select_hide(unselected: bool=False):
    """Hide selected faces

    :param unselected: Unselected, Hide unselected rather than selected objects
    :type unselected: bool
    """
    pass


def reverse_dict_old(dikt):
    """
    takes a dict and return a new dict with old values as key and old keys as values (in a list)

    example

    _reverse_dict({'AB04a':'b', 'AB04b': 'b', 'AB04c':'b', 'CC04x': 'c'})

    will return
        {'b': ['AB04a', 'AB04b', 'AB04c'], 'c': 'CC04x'}
    """
    new_dikt = {}
    for k, v in dikt.items():
        if v in new_dikt:
            new_dikt[v].append(k)
        else:
            new_dikt[v] = [k]
    return new_dikt


def get_delimiter(conf):
    """ get the delimiter used in the log files between values

        :param ConfigParser conf: the main config file
        :returns: the user-defined delimiter or the assumed default one (,)
    """
    if conf.has_option('control', 'delimiter'):
        d = conf.get('control', 'delimiter')
        d = d.replace('\\t', '\t')
        return d
    else:
        return ','


@staticmethod
def _do_stream(data, stream):
    """Helper function for _mergeStdout"""
    for line in data.splitlines(True):
        line = line.replace('\\n', '\n# ')
        if line.startswith('#'):
            stream.write(line)
        else:
            stream.write('# ' + line)
    if not line.endswith('\n'):
        stream.write('\n')


def list2ormp(result_obj):
    """Bizarrely, OpsRamp sometimes returns a simple list for
    Resources API calls instead of its usual results struct."""
    if isinstance(result_obj, dict):
        assert 'results' in result_obj
        assert 'totalResults' in result_obj
        return result_obj
    assert isinstance(result_obj, list)
    count = len(result_obj)
    retval = {'totalResults': count, 'pageSize': count, 'totalPages': 1,
        'pageNo': 1, 'previousPageNo': 0, 'nextPage': False,
        'descendingOrder': False, 'results': result_obj}
    return retval


def set_dbdir(dbdir_):
    """Sets the path to the directory where the JSON files should be
    stored. Calling this method side-steps the configuration settings in the
    `acorn.cfg` global config file.

    Args:
        dbdir_ (str): path to the dbdir; can be relative.
    """
    global dbdir
    dbdir = dbdir_


def _ensure_geometry_column(df):
    """
    Helper function to ensure the geometry column is called 'geometry'.
    If another column with that name exists, it will be dropped.
    """
    if not df._geometry_column_name == 'geometry':
        if 'geometry' in df.columns:
            df.drop('geometry', axis=1, inplace=True)
        df.rename(columns={df._geometry_column_name: 'geometry'}, copy=
            False, inplace=True)
        df.set_geometry('geometry', inplace=True)


def process_phylip_consense(tree):
    """ PHYLIP consense program generates tree that has branch length
    proportional to bootstrap support values. This function transforms the
    support values to node supports, and set all branch length to 1, which
    should be ignored when drawing.
    This is specific for PHYLIP consense only.
    """
    for node in tree.traverse('postorder'):
        node.support = float(node.dist) / 100.0
        node.dist = 1.0
    return tree


@classmethod
def _from_dict(cls, _dict):
    """Initialize a NluEnrichmentCategories object from a json dictionary."""
    args = {}
    xtra = _dict.copy()
    args.update(xtra)
    return cls(**args)


def intersection(u1, u2, v1, v2):
    """
    return the intersection of (u1, u2) and (v1, v2) or None if no intersection

    Example:

    intersec = intersection(0, 3, 2, 5)
    if intersec is not None:
        x0, x1 = intersec    --> 2, 3

    """
    x0 = u1 if u1 > v1 else v1
    x1 = u2 if u2 < v2 else v2
    return (x0, x1) if x0 < x1 else None


@classmethod
def from_string(cls, url):
    """
        Constructs an artifact from a maven syntax (groupid:artifactid:version)
        :type url: string
        """
    return cls(*url.split(':', 2))


@staticmethod
def parseDeltaDays(delta_days):
    """
        return list[days, hours, minutes, seconds] of a daltatime type data.
        """
    days = delta_days.days
    total_seconds = delta_days.seconds
    hours, res_hour = divmod(total_seconds, 3600)
    minutes, seconds = divmod(res_hour * 3600, 60)
    return {'days': days, 'hours': hours, 'minutes': minutes, 'seconds':
        seconds}


def is_rule(fun):
    """ Returns whether something is a rule or not """
    is_callable = hasattr(fun, '__call__')
    return is_callable and hasattr(fun, 'is_rule') and fun.is_rule


def findAll(txt, subStr):
    """
    Find the starting indicies of all instances of subStr in txt
    """
    indexList = []
    index = 0
    while True:
        try:
            index = txt.index(subStr, index)
        except ValueError:
            break
        indexList.append(int(index))
        index += 1
    return indexList


def search_repos(g, query):
    """search for repositires"""
    return g.search_repositories(query)


def log(img):
    """
        Element-wise natural log of an `Image`.

        If the `Image` is empty, returns the empty `Image`.

        Example
        -------
        >>> import descarteslabs.workflows as wf
        >>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1").pick_bands("red")
        >>> img.log().compute(geoctx) # doctest: +SKIP
        ImageResult:
        ...
        """
    from ..math import arithmetic
    return arithmetic.log(img)


@classmethod
def debug(cls, msg, duration=3, escaped=False):
    """
        Add a debug message
        """
    cls.__message(msg, 'debug', duration, escaped)


def urlToLink(entryRef):
    """ Move the entryRef "url" or "link" field into a URL in the "link" field

        Args:
            entryRef (obj): a bib database entry. It will be modified

        Returns:
            (bool): was a URL found and successfully converted?
    """
    if 'url' in entryRef.keys() and len(entryRef['url']) > 0:
        entryRef['link'] = entryRef['url']
        return True
    elif 'link' in entryRef.keys() and len(entryRef['link']) > 0:
        entryRef['link'] = entryRef['link']
        return True
    else:
        return False


def p_slice_list(p):
    """ slice_list : slice_item
                   | slice_list "," slice_item """
    if len(p) == 2:
        p[0] = [p[1]]
    else:
        p[0] = p[1] + [p[3]]


@classmethod
def can_view(cls, user):
    """
        Check that the given a user instance has access to the metric.

        This requires the user instance to have the
        :attr:`~django.contrib.auth.models.PermissionsMixin.is_superuser` and
        :attr:`~django.contrib.auth.models.PermissionsMixin.is_staff` flags as
        well as the
        :meth:`~django.contrib.auth.models.PermissionsMixin.has_perm` method.

        Users with ``is_superuser=True`` will always have access to a metric.
        Users with ``is_staff=True`` will have access if and only if the user
        has the permission :attr:`permission_name`.
        """
    return user.is_superuser or user.is_staff and user.has_perm(cls.
        permission_key)


def lovasz_grad(gt_sorted):
    """
    Computes gradient of the Lovasz extension w.r.t sorted errors
    See Alg. 1 in paper
    """
    p = len(gt_sorted)
    gts = gt_sorted.sum()
    intersection = gts - gt_sorted.float().cumsum(0)
    union = gts + (1 - gt_sorted).float().cumsum(0)
    jaccard = 1.0 - intersection / union
    if p > 1:
        jaccard[1:p] = jaccard[1:p] - jaccard[0:-1]
    return jaccard


def _uvw_scale_bias(image_parameters, grid_parameters):
    """Compute scale and bias values to turn UVW indices back into coordinates.

    The :mod:`preprocess` module quantises UVW coordinates; the values computed
    by this function can be used to convert them back to coordinates in
    wavelengths. Given quantised UV with grid cell :math:`g` and subpixel `s`,
    and W plane of :math:`w_p` in a W slice with centre :math:`w_0` wavelengths,
    the coordinates in wavelengths are

    .. math::

       uv &= uv_{scale}(oversample\\cdot g + s + 0.5)\\\\
       w &= w_0 + w_{scale}w_p + w_bias
    """
    ip = image_parameters
    gp = grid_parameters
    uv_scale = ip.cell_size / gp.oversample
    w_scale = gp.max_w / ((gp.w_slices - 0.5) * gp.w_planes)
    uv_scale = float(uv_scale / ip.wavelength)
    w_scale = float(w_scale / ip.wavelength)
    w_bias = (0.5 - 0.5 * gp.w_planes) * w_scale
    return uv_scale, w_scale, w_bias


def log10(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns element-wise Base-10 logarithmic value of the input.

    ``10**log10(x) = x``

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

    Defined in src/operator/tensor/elemwise_unary_op_logexp.cc:L93

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

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

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


def sample_color(location: int=(0, 0), merged: bool=False, palette: bool=False
    ):
    """Use the mouse to sample a color in the image

    :param location: Location
    :type location: int
    :param merged: Sample Merged, Sample the output display color
    :type merged: bool
    :param palette: Add to Palette
    :type palette: bool
    """
    pass


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


@classmethod
def sort(cls, runs, order_by_list):
    """Sorts a set of runs based on their natural ordering and an overriding set of order_bys.
        Runs are naturally ordered first by start time descending, then by run id for tie-breaking.
        """
    runs = sorted(runs, key=lambda run: (-run.info.start_time, run.info.
        run_uuid))
    if not order_by_list:
        return runs
    for order_by_clause in reversed(order_by_list):
        key_type, key, ascending = cls.parse_order_by(order_by_clause)
        runs = sorted(runs, key=lambda run: cls._get_value_for_sort(run,
            key_type, key, ascending), reverse=not ascending)
    return runs


@classmethod
def get_from_address(cls, address, topology):
    """
        Find node from one of its addresses and its topology.
        :param address: string
        :param topology: Topology instance
        :returns: Node object or None
        """
    address = '"{}"'.format(address)
    return cls.objects.filter(topology=topology, addresses__contains=address
        ).first()


@classmethod
def _from_iterable(cls, it):
    """Construct an instance of the class from any iterable input.

        Must override this method if the class constructor signature
        does not accept an iterable for an input.
        """
    return cls(it)


def points_with_surrounding_gaps(points):
    """
    This function makes sure that any gaps in the sequence provided have stopper points at their beginning
    and end so a graph will be drawn with correct 0 ranges. This is more efficient than filling in all points
    up to the maximum value. For example:

    input: [1,2,3,10,11,13]
    output [1,2,3,4,9,10,11,12,13]
    """
    points_with_gaps = []
    last_point = -1
    for point in points:
        if last_point + 1 == point:
            pass
        elif last_point + 2 == point:
            points_with_gaps.append(last_point + 1)
        else:
            points_with_gaps.append(last_point + 1)
            points_with_gaps.append(point - 1)
        points_with_gaps.append(point)
        last_point = point
    return points_with_gaps


def prep_carrier_query(npc, device, upg, forced):
    """
    Prepare carrier query XML.

    :param npc: MCC + MNC (see `func:return_npc`)
    :type npc: int

    :param device: Hexadecimal hardware ID.
    :type device: str

    :param upg: "upgrade" or "repair".
    :type upg: str

    :param forced: Force a software release.
    :type forced: str
    """
    query = (
        '<?xml version="1.0" encoding="UTF-8"?><updateDetailRequest version="2.2.1" authEchoTS="1366644680359"><clientProperties><hardware><pin>0x2FFFFFB3</pin><bsn>1128121361</bsn><imei>004401139269240</imei><id>0x{0}</id></hardware><network><homeNPC>0x{1}</homeNPC><iccid>89014104255505565333</iccid></network><software><currentLocale>en_US</currentLocale><legalLocale>en_US</legalLocale></software></clientProperties><updateDirectives><allowPatching type="REDBEND">true</allowPatching><upgradeMode>{2}</upgradeMode><provideDescriptions>false</provideDescriptions><provideFiles>true</provideFiles><queryType>NOTIFICATION_CHECK</queryType></updateDirectives><pollType>manual</pollType><resultPackageSetCriteria><softwareRelease softwareReleaseVersion="{3}" /><releaseIndependent><packageType operation="include">application</packageType></releaseIndependent></resultPackageSetCriteria></updateDetailRequest>'
        .format(device, npc, upg, forced))
    return query


def advance_time_delta(dt, timedelta):
    """Advances a datetime by a datetime.timedelta

    :param datetime dt: a specified date time
    :param datetime.timedelta timedelta:    time offset (delta)
    :returns:   a datetime incremented by delta
    :rtype:     datetime
    """
    return dt + timedelta


def fStrzs(floatstr):
    """DEPRECATED, use function L{fstrzs}.
    """
    from pygeodesy.streprs import fstrzs
    return fstrzs(floatstr)


def savefig(fig, *args, **kwargs):
    """
    Save figure with tight bounding box.
    From https://github.com/mwaskom/seaborn/blob/master/seaborn/axisgrid.py#L33
    """
    kwargs = kwargs.copy()
    kwargs.setdefault('bbox_inches', 'tight')
    fig.savefig(*args, **kwargs)


@staticmethod
def settings_to_dict(settings):
    """
        Make the settings readable for the widgets set settings method.

        Arguments:
        settings - Settings as dictionary.

        Return:
        None
        """
    settings_dict = {}
    idx = -1
    while idx < len(settings) - 1:
        idx += 1
        if settings[idx][0] == '###':
            key = settings[idx][1]
            if key == 'Frames':
                settings_dict[key] = []
            else:
                settings_dict[key] = {}
            continue
        if len(settings[idx]) == 1:
            settings[idx].append('')
        if key == 'Frames':
            setting = {}
            setting[settings[idx][0]] = settings[idx][1]
            for i in range(3):
                idx += 1
                setting[settings[idx][0]] = settings[idx][1]
            settings_dict[key].append(setting)
        elif key == 'Notification_widget':
            settings_dict[key].update({settings[idx][0]: [settings[idx][1],
                settings[idx][2]]})
        else:
            settings_dict[key].update({settings[idx][0]: settings[idx][1]})
    return settings_dict


def _is_mode_line(line):
    """
    `ls` output starts a category with a separate line like `Vertex Types:`, we need to recognize this line
    to know what follows it.
    """
    return line.endswith(':')


@staticmethod
def is_invertible():
    """Return True if the node can be inverted, False otherwise."""
    return False


@classmethod
def to_message(cls, value):
    """description of to_message"""
    try:
        return value.getMessage() % vars(value)
    except Exception:
        return value.getMessage()


@classmethod
def register(cls, unit):
    """
        Register a new named quantity, i.e., a unit.
        """
    cls._UNITS[unit.name] = unit


def set_censor_characters(censor_chars):
    """Sets the pool of censor characters. Input should be a single string
    containing all the censor charcters you'd like to use.
    Example: "@#$%^"

    """
    global _censor_chars
    _censor_chars = censor_chars


def make_target(scope, name):
    """Create a target from ``scope`` and ``name``.

    ``name`` is the name of the Emacs Lisp symbol to reference, and ``scope``
    is the scope in which to reference the symbol.  Both arguments are strings.

    Return the target name as string.

    """
    return 'el.{0}.{1}'.format(scope, name)


@staticmethod
def _call_method(obj, name):
    """
        Checks if a (file) object has a named method and returns the
        result of calling it.

        If the attribute does not exist or is not :py:func:`callable`,
        return :py:obj:`None`. Methods are assumed to be no-arg.

        Methods are expected to raise a :py:exc:`ValueError` if the file
        is closed. The error will be ignored and the return value will
        be :py:obj:`None`.
        """
    meth = getattr(obj, name, None)
    if meth is None or not callable(meth):
        return None
    try:
        return meth()
    except ValueError:
        return None


def nop():
    """ Function which does absolutely nothing (aka pass, noop). """
    pass


def _sims_parse(res):
    """Converts N/A to `nan` and otherwise tries to parse integers"""
    try:
        return int(res)
    except ValueError:
        if res.lower() == 'n/a':
            return float('nan')
        else:
            return res


@classmethod
def tuples(cls):
    """
        Returns a tuple formed by attributes for all the elements inside the
        class

        :return: tuple of n-elements-tuples
        """
    return tuple(cls._value2member_map_.keys())


@classmethod
def from_raw(cls, raw, owner):
    """
        Loads address translator with RAW address
        """
    return cls(owner.offset_to_addr(raw) - (owner.mapped_base if owner.
        _is_mapped else owner.linked_base), owner)


@classmethod
def garbage_collect(cls):
    """
        Deletes all Query records that have no daily hits or editors picks
        """
    extra_filter_kwargs = {'editors_picks__isnull': True} if hasattr(cls,
        'editors_picks') else {}
    cls.objects.filter(daily_hits__isnull=True, **extra_filter_kwargs).delete()


def mode_is_read(mode: str) ->bool:
    """
    Determine if an open mode is a read. Opening a file with `w+` or `a+` allows read and write.
    """
    return 'r' in mode or '+' in mode


def bundle(*addable):
    """ Getting addable objects (such as Matching) and composing them to one.
    When nothing is provided, this will raise a ValueError
    """
    if len(addable) <= 0:
        raise ValueError('Provide at least one Matching object')
    return sum(addable[1:], addable[0])


def _encode_action_type(routes, action_type):
    """
    Encode the outbound action type, apply routing and
    create MQTT topic.

    :param routes: The routing dict
    :type routes: dict

    :param action_type: The type of action
    :type action_type: str

    :returns: The routed MQTT topic
    """
    if not '/' in action_type:
        return action_type
    for handle, route in routes.items():
        if action_type.startswith('@' + handle):
            return action_type.replace('@' + handle, route)
    return action_type


def end_case(typ):
    """测完一个测试点后，该测试点状态为 [typ]"""
    print()


def json4Series(obj):
    """Converts a pandas.Series into a json-like object.

    Parameters
    ==========
    obj : pandas.Series
        input Series

    Returns
    =======
    json_like
        a json-like object

    Notes
    =====
    A json-like object contains 2 array-likes, each has length K. The first array represents the index array. The second array represents the value array.
    """
    return [obj.index.tolist(), obj.tolist()]


@classmethod
def from_strings(cls, *intervals):
    """
        These are intervals specified as "-10 -- 5", "0-10", and so on

        :param intervals:
        :return:
        """
    list_of_intervals = []
    for interval in intervals:
        imin, imax = cls._parse_interval(interval)
        list_of_intervals.append(cls.new_interval(imin, imax))
    return cls(list_of_intervals)


def normalize_hosts_and_ports(hosts_and_ports):
    """ normalize the various options of hosts_and_ports int a list of
        host and port tuples
    """
    if isinstance(hosts_and_ports[0], list) or isinstance(hosts_and_ports[0
        ], tuple):
        return hosts_and_ports
    return [hosts_and_ports]


@staticmethod
def to_delisle(reaumur):
    """ Convert reaumur to delisle """
    return (80 - reaumur) * 15 / 8


@classmethod
def from_stream(cls, stream):
    """
        Return a |_MarkerFinder| instance to find JFIF markers in *stream*.
        """
    return cls(stream)


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 readaline(file):
    """
    read a non-comment line.
    """
    while True:
        line = file.readline()
        if len(line) == 0:
            return line
        if line[0] != '#':
            return line


def shape_key_clear():
    """Clear weights for all shape keys

    """
    pass


def choose_words(length):
    """Randomly select LENGTH words, join them with hyphens, return the
        result."""