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

    The ".dev0" means dirty.

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


def bytes_to_str(num, suffix='B'):
    """
    Convert number to a human readable string with decimal prefix.

    :param float num: Value in given unit.
    :param str suffix: Unit suffix. Defaults to 'B'.
    :returns: Human readable string with decimal prefixes.
    :rtype: str
    """
    for unit in ('', 'K', 'M', 'G'):
        if abs(num) < 1024.0:
            return f'{num:3.1f}{unit}{suffix}'
        num /= 1024.0
    return f'{num:.1f}T{suffix}'


def json_home(url):
    """
    Canned response for the json_home call
    """
    return {'resources': {(url + '/{tenantId}/account'): {'href-template':
        '/v1.0/{tenantId}/account', 'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-account.html'
        , 'allow': ['GET', 'PUT'], 'representations': ['application/json',
        'application/xml'], 'accept-put': ['application/xml',
        'application/json']}}, (url + '/{tenantId}/agents'): {
        'href-template': '/v1.0/{tenantId}/agents', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agents.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/agents/{agentId}'): {
        'href-template': '/v1.0/{tenantId}/agents/{agentId}', 'href-vars':
        {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'agentId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/agentId'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agents.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/agents/{agentId}/connections'): {'href-template':
        '/v1.0/{tenantId}/agents/{agentId}/connections', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'agentId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/agentId'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agent-connections.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/agents/{agentId}/connections/{connId}'): {
        'href-template':
        '/v1.0/{tenantId}/agents/{agentId}/connections/{connId}',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'agentId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/agentId',
        'connId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/connId'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agent-connections.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/agents/{agentId}/host_info_types'): {'href-template':
        '/v1.0/{tenantId}/agents/{agentId}/host_info_types', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'agentId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/agentId'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agents.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/agents/{agentId}/host_info/{handlerType}'): {
        'href-template':
        '/v1.0/{tenantId}/agents/{agentId}/host_info/{handlerType}',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'agentId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/agentId',
        'handlerType':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/handlerType'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agents.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/agent_tokens'): {
        'href-template': '/v1.0/{tenantId}/agent_tokens', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agent-tokens.html'
        , 'allow': ['GET', 'POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url + '/{tenantId}/agent_tokens/{tokenId}'):
        {'href-template': '/v1.0/{tenantId}/agent_tokens/{tokenId}',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'tokenId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tokenId'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agent-tokens.html'
        , 'allow': ['GET', 'PUT', 'DELETE'], 'representations': [
        'application/json', 'application/xml'], 'accept-put': [
        'application/xml', 'application/json']}}, (url +
        '/{tenantId}/agent_installers'): {'href-template':
        '/v1.0/{tenantId}/agent_installers', 'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agent-installers.html'
        , 'allow': ['POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url +
        '/{tenantId}/agent_installers/{installerId.sh}'): {'href-template':
        '/v1.0/{tenantId}/agent_installers/{installerId.sh}', 'href-vars':
        {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'installerId.sh':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/installerId.sh'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agent-installers.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/agent_installers/{installerId}'): {'href-template':
        '/v1.0/{tenantId}/agent_installers/{installerId}', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'installerId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/installerId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agent-installers.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/monitoring_zones'): {
        'href-template': '/v1.0/{tenantId}/monitoring_zones', 'href-vars':
        {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-monitoring-zones.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/monitoring_zones/{monitoringZoneId}'): {
        'href-template':
        '/v1.0/{tenantId}/monitoring_zones/{monitoringZoneId}', 'href-vars':
        {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'monitoringZoneId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/monitoringZoneId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-monitoring-zones.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/monitoring_zones/{monitoringZoneId}/traceroute'): {
        'href-template':
        '/v1.0/{tenantId}/monitoring_zones/{monitoringZoneId}/traceroute',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'monitoringZoneId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/monitoringZoneId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-monitoring-zones.html'
        , 'allow': ['POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url + '/{tenantId}/changelogs/alarms'): {
        'href-template': '/v1.0/{tenantId}/changelogs/alarms', 'href-vars':
        {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-alarms.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/entities'): {
        'href-template': '/v1.0/{tenantId}/entities', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-entities.html'
        , 'allow': ['GET', 'POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url + '/{tenantId}/entities/{entityId}'): {
        'href-template': '/v1.0/{tenantId}/entities/{entityId}',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-entities.html'
        , 'allow': ['GET', 'PUT', 'DELETE'], 'representations': [
        'application/json', 'application/xml'], 'accept-put': [
        'application/xml', 'application/json']}}, (url +
        '/{tenantId}/entities/{entityId}/checks'): {'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/checks', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-checks.html'
        , 'allow': ['GET', 'POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url +
        '/{tenantId}/entities/{entityId}/checks/{checkId}'): {
        'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/checks/{checkId}',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId',
        'checkId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/checkId'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-checks.html'
        , 'allow': ['GET', 'PUT', 'DELETE'], 'representations': [
        'application/json', 'application/xml'], 'accept-put': [
        'application/xml', 'application/json']}}, (url +
        '/{tenantId}/entities/{entityId}/checks/{checkId}/test'): {
        'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/checks/{checkId}/test',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId',
        'checkId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/checkId'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-checks.html'
        , 'allow': ['POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url +
        '/{tenantId}/entities/{entityId}/test-check'): {'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/test-check', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-checks.html'
        , 'allow': ['POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url +
        '/{tenantId}/entities/{entityId}/alarms'): {'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/alarms', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-alarms.html'
        , 'allow': ['GET', 'POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url +
        '/{tenantId}/entities/{entityId}/alarms/{alarmId}'): {
        'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/alarms/{alarmId}',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId',
        'alarmId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/alarmId'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-alarms.html'
        , 'allow': ['GET', 'PUT', 'DELETE'], 'representations': [
        'application/json', 'application/xml'], 'accept-put': [
        'application/xml', 'application/json']}}, (url +
        '/{tenantId}/entities/{entityId}/test-alarm'): {'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/test-alarm', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-alarms.html'
        , 'allow': ['POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url +
        '/{tenantId}/entities/{entityId}/agent/host_info/{handlerType}'): {
        'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/agent/host_info/{handlerType}',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId',
        'handlerType':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/handlerType'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agents.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/entities/{entityId}/agent/check_types/{checkType}/targets'
        ): {'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/agent/check_types/{checkType}/targets'
        , 'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId',
        'checkType':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/checkType'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agents.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/entities/{entityId}/alarms/{alarmId}/notification_history'
        ): {'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/alarms/{alarmId}/notification_history'
        , 'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId',
        'alarmId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/alarmId'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-alarms.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/entities/{entityId}/alarms/{alarmId}/notification_history/{checkId}'
        ): {'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/alarms/{alarmId}/notification_history/{checkId}'
        , 'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId',
        'alarmId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/alarmId',
        'checkId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/checkId'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-alarms.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/entities/{entityId}/alarms/{alarmId}/notification_history/{checkId}/{uuid}'
        ): {'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/alarms/{alarmId}/notification_history/{checkId}/{uuid}'
        , 'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId',
        'alarmId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/alarmId',
        'checkId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/checkId',
        'uuid':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/uuid'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-alarms.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/check_types'): {
        'href-template': '/v1.0/{tenantId}/check_types', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-check-types.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/check_types/{checkTypeId}'): {'href-template':
        '/v1.0/{tenantId}/check_types/{checkTypeId}', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'checkTypeId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/checkTypeId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-check-types.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/notification_types'): {
        'href-template': '/v1.0/{tenantId}/notification_types', 'href-vars':
        {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-notification-types.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/notification_types/{notificationTypeId}'): {
        'href-template':
        '/v1.0/{tenantId}/notification_types/{notificationTypeId}',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'notificationTypeId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/notificationTypeId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-notification-types.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/notifications'): {
        'href-template': '/v1.0/{tenantId}/notifications', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-notifications.html'
        , 'allow': ['GET', 'POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url +
        '/{tenantId}/notifications/{notificationId}'): {'href-template':
        '/v1.0/{tenantId}/notifications/{notificationId}', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'notificationId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/notificationId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-notifications.html'
        , 'allow': ['GET', 'PUT', 'DELETE'], 'representations': [
        'application/json', 'application/xml'], 'accept-put': [
        'application/xml', 'application/json']}}, (url +
        '/{tenantId}/notifications/{notificationId}/test'): {
        'href-template':
        '/v1.0/{tenantId}/notifications/{notificationId}/test', 'href-vars':
        {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'notificationId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/notificationId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-notifications.html'
        , 'allow': ['POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url + '/{tenantId}/test-notification'): {
        'href-template': '/v1.0/{tenantId}/test-notification', 'href-vars':
        {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-notifications.html'
        , 'allow': ['POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url + '/{tenantId}/notification_plans'): {
        'href-template': '/v1.0/{tenantId}/notification_plans', 'href-vars':
        {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-notification-plans.html'
        , 'allow': ['GET', 'POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url +
        '/{tenantId}/notification_plans/{notificationPlanId}'): {
        'href-template':
        '/v1.0/{tenantId}/notification_plans/{notificationPlanId}',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'notificationPlanId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/notificationPlanId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-notification-plans.html'
        , 'allow': ['GET', 'PUT', 'DELETE'], 'representations': [
        'application/json', 'application/xml'], 'accept-put': [
        'application/xml', 'application/json']}}, (url +
        '/{tenantId}/audits'): {'href-template': '/v1.0/{tenantId}/audits',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-audits.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/limits'): {
        'href-template': '/v1.0/{tenantId}/limits', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-limits.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/usage'): {'href-template':
        '/v1.0/{tenantId}/usage', 'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-usage.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/suppressions/{suppressionId}'): {'href-template':
        '/v1.0/{tenantId}/suppressions/{suppressionId}', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'suppressionId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/suppressionId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-suppressions.html'
        , 'allow': ['GET', 'PUT', 'DELETE'], 'representations': [
        'application/json', 'application/xml'], 'accept-put': [
        'application/xml', 'application/json']}}, (url +
        '/{tenantId}/suppressions'): {'href-template':
        '/v1.0/{tenantId}/suppressions', 'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-suppressions.html'
        , 'allow': ['POST', 'GET'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url + '/{tenantId}/suppression_logs'): {
        'href-template': '/v1.0/{tenantId}/suppression_logs', 'href-vars':
        {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-suppression-log_entries.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/alarm_examples'): {
        'href-template': '/v1.0/{tenantId}/alarm_examples', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-alarm-examples.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/alarm_examples/{alarmExampleId}'): {'href-template':
        '/v1.0/{tenantId}/alarm_examples/{alarmExampleId}', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'alarmExampleId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/alarmExampleId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-alarm-examples.html'
        , 'allow': ['GET', 'POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url + '/{tenantId}/views/overview'): {
        'href-template': '/v1.0/{tenantId}/views/overview', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-views.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/views/metric_list'): {
        'href-template': '/v1.0/{tenantId}/views/metric_list', 'href-vars':
        {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-views.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/views/agent_host_info'):
        {'href-template': '/v1.0/{tenantId}/views/agent_host_info',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-views.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/views/latest_alarm_states'): {'href-template':
        '/v1.0/{tenantId}/views/latest_alarm_states', 'href-vars': {
        'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-views.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/__experiments/json_home'):
        {'href-template': '/v1.0/{tenantId}/__experiments/json_home',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-json-home.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url + '/{tenantId}/__experiments/multiplot'):
        {'href-template': '/v1.0/{tenantId}/__experiments/multiplot',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-rollups.html'
        , 'allow': ['POST'], 'representations': ['application/json',
        'application/xml'], 'accept-post': ['application/xml',
        'application/json']}}, (url +
        '/{tenantId}/entities/{entityId}/checks/{checkId}/metrics/{metricName}/plot'
        ): {'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/checks/{checkId}/metrics/{metricName}/plot'
        , 'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId',
        'checkId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/checkId',
        'metricName':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/metricName'
        }, 'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-rollups.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}, (url +
        '/{tenantId}/entities/{entityId}/checks/{checkId}/metrics'): {
        'href-template':
        '/v1.0/{tenantId}/entities/{entityId}/checks/{checkId}/metrics',
        'href-vars': {'tenantId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/tenantId',
        'entityId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/entityId',
        'checkId':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/params/checkId'},
        'hints': {'docs':
        'http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-metric-names.html'
        , 'allow': ['GET'], 'representations': ['application/json',
        'application/xml']}}}}


def point_velocities(axis_mapping, point, entry=True):
    """Find the velocities of each axis over the entry/exit of current point"""
    velocities = {}
    for axis_name, motor_info in axis_mapping.items():
        dp = point.upper[axis_name] - point.lower[axis_name]
        vp = dp / point.duration
        if entry:
            dhalf = point.positions[axis_name] - point.lower[axis_name]
        else:
            dhalf = point.upper[axis_name] - point.positions[axis_name]
        velocity = 4 * dhalf / point.duration - vp
        assert abs(velocity
            ) < motor_info.max_velocity, 'Velocity %s invalid for %r with max_velocity %s' % (
            velocity, axis_name, motor_info.max_velocity)
        velocities[axis_name] = velocity
    return velocities


def host_port(mqtt_config):
    """Return the host and port from a :class:`.MQTTConfig` object.

    Args:
        mqtt_config (:class:`.MQTTConfig`): The MQTT connection settings.

    Returns:
        (str, int): A tuple with the host and port defined in the MQTT
        connection settings.

    .. versionadded:: 0.6.0
    """
    host_port = mqtt_config.broker_address.split(':')
    if mqtt_config.tls.hostname:
        host = mqtt_config.tls.hostname
    else:
        host = host_port[0]
    port = int(host_port[1])
    return host, port


def loop_to_region(select_bigger: bool=False):
    """Select region of faces inside of a selected loop of edges

    :param select_bigger: Select Bigger, Select bigger regions instead of smaller ones
    :type select_bigger: bool
    """
    pass


def dolly(mx: int=0, my: int=0, delta: int=0, use_cursor_init: bool=True):
    """Dolly in/out in the view

    :param mx: Region Position X
    :type mx: int
    :param my: Region Position Y
    :type my: int
    :param delta: Delta
    :type delta: int
    :param use_cursor_init: Cursor Init, Use initial cursor position
    :type use_cursor_init: bool
    """
    pass


def get_partner_regex(pdb_name, bound):
    """
    Get partner regex for provided filename.

    e.g. ligand 11as_r_u_cleaned.pdb1 would give 11as_._u_cleaned.pdb1.
    """
    new_pdb_name = list(pdb_name)
    new_pdb_name[5] = '.'
    new_pdb_name[7] = 'b' if bound else 'u'
    new_pdb_name = ['^'] + new_pdb_name + ['$']
    return ''.join(new_pdb_name)


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 _closure(obj, iter_property_name):
    """
    I iter over the closure of the method named by iter_property_name, starting
    at obj.
    """
    seen = set([obj])
    queue = set(seen)
    while queue:
        i = queue.pop()
        yield i
        for j in getattr(i, iter_property_name):
            if not j in seen:
                seen.add(j)
                queue.add(j)


def convert_chromosome(chromosome, dest='ensembl'):
    """
    Interconverts chromosome names from UCSC or Ensembl to the dialect specified by :param:`dest`

    :param chromosome:
    :param dest:
    :return:
    """
    if dest == 'ensembl':
        if chromosome == 'chrM':
            return 'MT'
        elif chromosome[:3].lower() == 'chr':
            return chromosome[3:]
        else:
            return chromosome
    elif dest == 'ucsc':
        if chromosome == 'MT':
            return 'chrM'
        elif chromosome[:3].lower() == 'chr':
            return chromosome
        else:
            return 'chr{}'.format(chromosome)
    else:
        raise ValueError('Unknown destination {}'.format(dest))


def create_orders(data, rename, **kwargs):
    """
    create an orders dataframe from an existing dataframe
    by renaming columns and providing additional columns
    data
        dataframe
    rename
        columns to be renamed as dictionary
    kwargs
        key value pairs with key being column names
        and values being dataframe values
    """
    data = data.rename(rename, axis='columns')
    for k, v in kwargs.items():
        data[k] = v
    return data


def retractboundary(repo, tr, targetphase, nodes):
    """Set nodes back to a phase changing other nodes phases if
    necessary.

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

    Simplify boundary to contains phase roots only."""
    phcache = repo._phasecache.copy()
    phcache.retractboundary(repo, tr, targetphase, nodes)
    repo._phasecache.replace(phcache)


def lmap(fn, *iterables):
    """Call map and then cast to list."""
    return list(map(fn, *iterables))


def filter_unexpected_features(insertions):
    """Filters insertions that have non splice-acceptor/donor features.

    This filter removes any insertions that splice to tranposon features
    that aren't splice-acceptors or splice-donors. This is based on the
    premise that these other sites are unlikely to be involved in any
    splicing and that therefore these insertions are likely to be false
    positives of the fusion identification.

    Parameters
    ----------
    insertions : iterable[Insertion]
        Insertions to filter.

    Yields
    ------
    Insertion
        Next filtered insertion.

    """
    for ins in insertions:
        if ins.metadata['feature_type'] in {'SA', 'SD'}:
            yield ins


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

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

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


def flat_ind_zp_so3(l, m, n, b):
    """
    The SO3 spectrum consists of matrices f_hat^l of size (2l+1, 2l+1) for l=0, ..., L_max = b - 1.
    These can be stored in a zero-padded array A of shape (b, 2b, 2b) with axes l, m, n with zero padding around
     the center of the last two axes. If we flatten this array A we get a vector v of size 4b^3.
    This function gives the flat index in this array v corresponding to element (l, m, n)

    The zero-based 3D index of (l, m, n) in A is (l, b + m, b + n).
    The corresponding flat index is i = l * 4b^2 + (b + m) * 2b + b + n

    :param l, m, n: spectral indices
    :return: index of (l, m, n) in flat zero-padded vector
    """
    return l * 4 * b ** 2 + (b + m) * 2 * b + b + n


def mask(length, offset=0):
    """
    Generate a bitmask with the given parameter.

    :param length:  The bit length of the mask.
    :param offset:  The offset of the mask from the LSB bit. [default: 0]
    :return:        An integer representing the bit mask.
    """
    return (1 << length) - 1 << offset


def select_all_toggle():
    """Select or deselect all files

    """
    pass


@classmethod
def help(cls, what='operators'):
    """returns list of available operators"""
    print(cls._operators)


def __call__():
    """Return a default object created to be populated.
        """


def _str_or_file(argument):
    """Helper type to parse a string as a file.

    This is because of the implementation of @<file> didn't work as expected originally,
    and this might not be the best practice way to do a cli application.
    """
    if argument.startswith('@'):
        with open(argument[1:], 'r') as f:
            output = ''.join(f.readlines())
    else:
        output = argument
    return output


def clear() ->None:
    """
    Clear all the pixels.
    """


def getCell(item, column):
    """Render the cell contents for the item and column."""


def load_pkg_resources(finder, module):
    """pkg_resources dynamic load modules in a subpackage."""
    finder.IncludePackage('pkg_resources._vendor')


def get_object_by_path(path, root=False):
    """Return an object by its path, adjusting its type if it is a
        root.
        """


def singleChoiceWithSubParams(parameters, name, type_converter=str):
    """ single choice with sub parameters value and chosen subparameters. Returns -1 and None if no value was chosen.
    :param parameters: the parameters tree.
    :param name: the name of the parameter.
    :param type_converter: function to convert the chosen value to a different type (e.g. str, float, int). default = 'str'"""
    param = parameters.find(".//SingleChoiceWithSubParams[@Name='{name}']".
        format(name=name))
    value = int(param.find('Value').text)
    values = param.find('Values')
    if value < 0:
        return value, None
    return type_converter(values[value].text), param.findall(
        'SubParams/Parameters')[value]


def delocalize_uncompressed_verts(uncomp_verts, local_nodes):
    """TODO: Update this function to also work on parsed vert data."""
    local_node_ct = len(local_nodes)
    for i in range(57, len(uncomp_verts), 68):
        if uncomp_verts[i] < local_node_ct:
            uncomp_verts[i] = local_nodes[uncomp_verts[i]]
        i += 2
        if uncomp_verts[i] < local_node_ct:
            uncomp_verts[i] = local_nodes[uncomp_verts[i]]


def binary_focal_loss(gt, pr, gamma=2.0, alpha=0.25, **kwargs):
    """Implementation of Focal Loss from the paper in binary classification

    Formula:
        loss = - gt * alpha * ((1 - pr)^gamma) * log(pr) \\
               - (1 - gt) * alpha * (pr^gamma) * log(1 - pr)

    Args:
        gt: ground truth 4D keras tensor (B, H, W, C) or (B, C, H, W)
        pr: prediction 4D keras tensor (B, H, W, C) or (B, C, H, W)
        alpha: the same as weighting factor in balanced cross entropy, default 0.25
        gamma: focusing parameter for modulating factor (1-p), default 2.0

    """
    backend = kwargs['backend']
    pr = backend.clip(pr, backend.epsilon(), 1.0 - backend.epsilon())
    loss_1 = -gt * (alpha * backend.pow(1 - pr, gamma) * backend.log(pr))
    loss_0 = -(1 - gt) * ((1 - alpha) * backend.pow(pr, gamma) * backend.
        log(1 - pr))
    loss = backend.mean(loss_0 + loss_1)
    return loss


@classmethod
def default(cls, default=None):
    """Retrieve the active schema or the default."""
    if default is not None:
        cls._default_schema = default
    return cls._default_schema


@classmethod
def dictify_entity(cls, entity):
    """Turn XML entity into a dictionary"""
    output = entity.attrib
    relations = {}
    if 'type' in output:
        output['_type'] = output['type']
        del output['type']
    for prop in entity:
        if prop.tag == 'entity':
            ent = cls.dictify_entity(prop)
            if prop.attrib.get('rel') == ent.get('_type'):
                relations[prop.attrib.get('rel')] = ent
            else:
                collection = cls.get_collection_name(prop, ent)
                relations.setdefault(collection, []).append(ent)
        else:
            output[prop.attrib['name']] = prop.attrib['value']
    if relations:
        output['relations'] = relations
    return output


@conf
def common_flags_ldc2(conf):
    """
	Sets the D flags required by *ldc2*
	"""
    v = conf.env
    v.D_SRC_F = ['-c']
    v.D_TGT_F = '-of%s'
    v.D_LINKER = v.D
    v.DLNK_SRC_F = ''
    v.DLNK_TGT_F = '-of%s'
    v.DINC_ST = '-I%s'
    v.DSHLIB_MARKER = v.DSTLIB_MARKER = ''
    v.DSTLIB_ST = v.DSHLIB_ST = '-L-l%s'
    v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L-L%s'
    v.LINKFLAGS_dshlib = ['-L-shared']
    v.DHEADER_ext = '.di'
    v.DFLAGS_d_with_header = ['-H', '-Hf']
    v.D_HDR_F = '%s'
    v.LINKFLAGS = []
    v.DFLAGS_dshlib = ['-relocation-model=pic']


def hex_max(value):
    """Gets the maximum color channel value for a hex color value.
    >>> hex_max('#ddeeff')
    255
    >>> hex_max('#00001111aaaa')
    65535
    """
    value = value.lstrip('#')
    return int('f' * (len(value) / 3), 16)


def _first_line(path):
    """return the first line of a text file."""
    f = open(path, 'r')
    for line in f:
        f.close()
        return line


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

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

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


def make_color_tuple(color):
    """
    turn something like "#000000" into 0,0,0
    or "#FFFFFF into "255,255,255"
    """
    R = color[1:3]
    G = color[3:5]
    B = color[5:7]
    R = int(R, 16)
    G = int(G, 16)
    B = int(B, 16)
    return R, G, B


def modify_nb_possibilities(unmodified_nb_possibilities):
    """
    Returns the number of possibilities of generation for an item that has
    a case generation modifier, given the number of possibilities for
    the same item without this modifier.
    """
    return 2 * unmodified_nb_possibilities


def debt_to_asset_ratio(debt, assets):
    """Computes debt-to-asset ratio.

    @params
    -------
    debt: total debt
    assets: total assets

    returns
    -------
    Debt-to-asset ratio, int or float

    explanation
    -----------

    """
    return debt / assets


def get_rnn_hidden_state(h):
    """Returns h_t transparently regardless of RNN type."""
    return h if not isinstance(h, tuple) else h[0]


def decode_utf8(input_iterator):
    """
    Generator that decodes a utf-8 encoded
    input line by line
    """
    for l in input_iterator:
        yield l if isinstance(l, str) else l.decode('utf-8')


def p_simple_expr_identifier_full(p):
    """simple_expr : identifier '.' identifier"""
    p[0] = 'IDENTIFIER', p[1] + '.' + p[3]


def ipkg_meta_from_pkg(pkg):
    """Return meta dict for Installed pkg from a PackageDescription
    instance."""
    meta = {}
    for m in ['name', 'version', 'summary', 'url', 'author', 'author_email',
        'license', 'download_url', 'description', 'platforms',
        'classifiers', 'install_requires', 'top_levels']:
        meta[m] = getattr(pkg, m)
    return meta


@classmethod
def toBool(cls, value):
    """ converts to bool

        :param value: variable to convert
        :type value: any
        :returns: result in bool type
        :rtype: :obj:`bool`
        """
    if type(value).__name__ == 'str' or type(value).__name__ == 'unicode':
        lvalue = value.strip().lower()
        if lvalue == 'false' or lvalue == '0':
            return False
        else:
            return True
    elif value:
        return True
    return False


def string_literal(content):
    """
    Choose a string literal that can wrap our string.

    If your string contains a ``'`` the result will be wrapped in ``"``.
    If your string contains a ``"`` the result will be wrapped in ``'``.

    Cannot currently handle strings which contain both ``"`` and ``'``.
    """
    if '"' in content and "'" in content:
        raise ValueError('Cannot represent this string in XPath')
    if '"' in content:
        content = "'%s'" % content
    else:
        content = '"%s"' % content
    return content


def set_namedtuple_defaults(namedtuple, default=None):
    """Set *all* of the fields for a given nametuple to a singular value.

    Modifies the tuple in place, but returns it anyway.

    More info:
    https://stackoverflow.com/a/18348004

    :param namedtuple: A constructed collections.namedtuple
    :param default: The default value to set.

    :returns: the modified namedtuple
    """
    namedtuple.__new__.__defaults__ = (default,) * len(namedtuple._fields)
    return namedtuple


def get_delim(delim):
    """
    manage special conversions for difficult bash characters
    """
    if delim == 'newline':
        delim = '\n'
    elif delim == 'tab':
        delim = '\t'
    elif delim == 'space':
        delim = ' '
    return delim


def greedy(yet_to_be_covered, set2label, set2score):
    """
    Greedy set coverage.
    :param yet_to_be_covered: set of interest
    :param set2label: dict {set: label} available sets and their labels
    :param set2score: dict {set: score}
    :return: iterator of tuples (set, label) corresponding to the selected sets for the coverage
    """
    yet_to_be_covered = set(yet_to_be_covered)
    while yet_to_be_covered and set2label:
        s = max(set2label.keys(), key=lambda candidate_terms: (len(set(
            candidate_terms) & yet_to_be_covered), set2score[candidate_terms]))
        result = set(s)
        yield result & yet_to_be_covered, set2label[s]
        yet_to_be_covered -= result
        del set2label[s]


def stripInstructions(font):
    """Remove all TrueType instructions from the font.
    """
    """
        TODO: Fix docTests

        >>> from pagebot.fonttoolbox.objects.font import findFont
        >>> pf = findFont('Bungee-Regular')
        >>> font = pf.ttFont
        >>> byteCode = font["glyf"]["a"].program.getBytecode()
        >>> len(byteCode)
        58
        >>> font.has_key("cvt ")
        1
        >>> stripInstructions(font)
        >>> byteCode = font["glyf"]["a"].program.getBytecode()
        >>> len(byteCode)
        0
        >>> font.has_key("cvt ")
        0
    """
    glyfTable = font['glyf']
    for gn in glyfTable.keys():
        g = glyfTable[gn]
        if g.isComposite():
            if hasattr(g, 'program'):
                del g.program
        elif hasattr(g, 'program'):
            g.program.fromBytecode([])
    tablesToDelete = ['cvt ', 'prep', 'fpgm']
    for tag in tablesToDelete:
        if font.has_key(tag):
            del font[tag]


@classmethod
def set_class_default(mcs, model, attr, value, instances=False):
    """Set DEFAULT attribute for Model class

        Arguments:
        model -- name of model class
        attr -- attribute name
        value -- new attribute value

        Keyword arguments:
        instances -- update instances too (default=False)
        """
    cls = mcs.__classes__[model]
    if attr in cls.REPLACE:
        attr = cls.REPLACE[attr]
    if attr in cls.DEFAULT:
        cls.DEFAULT[attr] = value
    if instances:
        cls.set_instances_default(attr, value)


def handle_smsmt(message):
    """ Called right after an SMS-MT is sent successfuly """
    return


@classmethod
def indexOf(cls, data, pattern, index, count):
    """
        Finds the first occurrence of the pattern in the text.
        data : Data where to find.
        pattern : Search pattern.
        index : Byte index to start.
        count : Count of bytes to search.
        Return True if pattern is found.
        """
    failure = cls.__computeFailure(pattern)
    j = 0
    if not data or len(data) < index:
        return -1
    for i in range(index, count):
        while j > 0 and pattern[j] != data[i]:
            j = failure[j - 1]
        if pattern[j] == data[i]:
            j = j + 1
        if j == len(pattern):
            return i - len(pattern) + 1
    return -1


def path_reference(filepath: str, base_src: str, base_dst: str, mode: str=
    'AUTO', copy_subdir: str='', copy_set: set=None, library:
    'bpy.types.Library'=None) ->str:
    """Return a filepath relative to a destination directory, for use with exporters.

    :param filepath: the file path to return, supporting blenders relative ‘//’ prefix.
    :type filepath: str
    :param base_src: the directory the filepath is relative too (normally the blend file).
    :type base_src: str
    :param base_dst: the directory the filepath will be referenced from (normally the export path).
    :type base_dst: str
    :param mode: the method used get the path in [‘AUTO’, ‘ABSOLUTE’, ‘RELATIVE’, ‘MATCH’, ‘STRIP’, ‘COPY’]
    :type mode: str
    :param copy_subdir: the subdirectory of base_dst to use when mode=’COPY’.
    :type copy_subdir: str
    :param copy_set: collect from/to pairs when mode=’COPY’, pass to path_reference_copy when exporting is done.
    :type copy_set: set
    :param library: The library this path is relative to.
    :type library: 'bpy.types.Library'
    :return:  the new filepath.
    """
    pass


def _loop_once():
    """Run the main loop once
    """
    pass


@classmethod
def beliefs(cls):
    """
        Not applicable for gliders
        """
    return {}


def get_new_config(proj):
    """Returns the dictionary representing the configuration for a newly-added
    project that has never been built before."""
    return {'taint': False, 'enable': True, 'args': []}


def cubic_spline(x1, x2, f1, f2, df1, df2):
    """
    Method to compute the coefficients of a smoothing polynomial.

    Parameters
    ----------
    x1: float
        point on the x-axis at which the smoothing polynomial begins
    x2: float
        point on the x-axis at which the smoothing polynomial ens
    f1: float
        function evaluated at x1
    f2: float
        function evaluated at x2
    df1: float
        derivative evaluated at x1
    df2: float
        derivative evaluated at x2

    Returns
    -------
    A tuple with the smoothing polynomail coefficients starting with the cubic term.
    """
    a = (2 * (f1 - f2) - (x1 - x2) * (df2 + df1)) / (x2 ** 3 - x1 ** 3 + 3 *
        x1 * x2 * (x1 - x2))
    b = (df1 - df2 + 3 * (x2 ** 2 - x1 ** 2) * a) / (2 * (x1 - x2))
    c = df2 - 3 * x2 ** 2 * a - 2 * x2 * b
    d = f2 - x2 ** 3 * a - x2 ** 2 * b - x2 * c
    return a, b, c, d


def getifname(sock):
    """Return interface name of `sock`"""
    return sock.getsockname()[0]


def register_plugin(cls, plugin):
    """Add the plugin to the plugin list and perform any registration logic"""
    cls.plugins.append(plugin)


@classmethod
def match_header(cls, header):
    """
        This class should never be instantiated directly.  Either a standard
        extension HDU type should be used for a specific extension, or
        NonstandardExtHDU should be used.
        """
    raise NotImplementedError


def s2itup(comp):
    """
    Convert string in the form ``xx``, ``xyz`` into tuple of two (three) indices
    that can be used to slice susceptibility tensors (numpy array).

    >>> assert s2itup("yy") == (1, 1)
    >>> assert s2itup("xyz") == (0, 1, 2)
    """
    d = {'x': 0, 'y': 1, 'z': 2}
    comp = str(comp).strip()
    if len(comp) == 2:
        return d[comp[0]], d[comp[1]]
    elif len(comp) == 3:
        return d[comp[0]], d[comp[1]], d[comp[2]]
    else:
        raise ValueError(
            'Expecting component in the form `xy` or `xyz` but got `%s`' % comp
            )


def copy_file(stream, target, maxread=-1, buffer_size=2 * 16):
    """ Read from :stream and write to :target until :maxread or EOF. """
    size, read = 0, stream.read
    while 1:
        to_read = buffer_size if maxread < 0 else min(buffer_size, maxread -
            size)
        part = read(to_read)
        if not part:
            return size
        target.write(part)
        size += len(part)


def rename_NRPS_domains(synthase):
    """Replace domain types in Hybrid and NRPS Synthases.

    The acyl carrier protein (ACP) domain in PKSs is homologous to the thioester
    domain of the peptide carrier protein (PCP) domain in NRPSs, and as such, both
    PKS and NRPS will report the same conserved domain hit. In NRPS, it is
    convention to name these T, i.e.::

        A-ACP-C --> A-T-C

    In hybrid PKS-NRPS, this replacement is made in the NRPS module of the synthase.
    Thus, this function looks for a condensation (C) domain that typically signals
    the beginning of such a module, and replaces any ACP with T after that domain.

    An example PKS-NRPS domain architecture may resemble::

        KS-AT-DH-ER-KR-ACP-C-A-T-R

    Thioester reductase (TR) domains are generally written as R in NRPS, thus the
    replacement here.

    Parameters
    ----------
    synthase : models.Synthase
        An NRPS or Hybrid Synthase object.

    Raises
    ------
    ValueError
        If `type` is not 'Hybrid' or 'NRPS'.
    """
    if synthase.type not in ('Hybrid', 'NRPS'):
        raise ValueError("Expected 'Hybrid' or 'NRPS'")
    start, replace = 0, {'ACP': 'T', 'TR': 'R'}
    if synthase.type == 'Hybrid':
        for start, domain in enumerate(synthase.domains):
            if domain.type in ('C', 'E'):
                break
    for domain in synthase.domains[start:]:
        if domain.type in replace:
            domain.type = replace[domain.type]


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 _crop_filter(input_filter, scale, radius=None):
    """
    Crop an image domain filter
    """
    ndim = input_filter.ndim
    if radius is None:
        radius = 4 * 2 ** scale
    if ndim == 2:
        nx, ny = input_filter.shape
        output_filter = input_filter[int(nx / 2 - radius):int(nx / 2 +
            radius + 1), int(ny / 2 - radius):int(ny / 2 + radius + 1)]
    elif ndim == 3:
        nx, ny, nz = input_filter.shape
        output_filter = input_filter[int(nx / 2 - radius):int(nx / 2 +
            radius + 1), int(ny / 2 - radius):int(ny / 2 + radius + 1), int
            (nz / 2 - radius):int(nz / 2 + radius + 1)]
    else:
        raise RuntimeError(
            'Unsupported number of dimensions {}. We only supports 2 or 3D arrays.'
            .format(ndim))
    return output_filter


def myfloat(string):
    """A replacement for float() which will return a large number if it finds a * in the string """
    if '*' in string:
        return 9999.999
    else:
        return float(string)


def update_ipmi_properties(task):
    """Update ipmi properties to node driver_info.

    :param task: A task from TaskManager.
    """
    node = task.node
    info = node.driver_info
    info['ipmi_address'] = info.get('irmc_address')
    info['ipmi_username'] = info.get('irmc_username')
    info['ipmi_password'] = info.get('irmc_password')
    task.node.driver_info = info


@classmethod
def is_mine(cls, pathname, filename='*', light=True, first=False):
    """Check if it can handle the report file.

        :param str pathname: Path to the report directory.
        :param str filename: Regex matching the report file.
        :param bool light: `True` to only parse the ranking of the findings from the report.
        :param bool first: Only process first file (``True``) or each file that matched (``False``).

        :raises IOError: when the report file cannot be found.
        :raises OSError: when the report file cannot be found.

        :return: `True` if it supports the report, `False` otherwise.
        :rtype: :class:`bool`

        """
    stream = cls.handle_file(pathname, filename, first=first)
    if stream and stream[0].startswith('HTTP'):
        return True
    return False


def _escape_dn_value(val):
    """Escape special characters in RFC4514 Distinguished Name value."""
    if not val:
        return ''
    val = val.replace('\\', '\\\\')
    val = val.replace('"', '\\"')
    val = val.replace('+', '\\+')
    val = val.replace(',', '\\,')
    val = val.replace(';', '\\;')
    val = val.replace('<', '\\<')
    val = val.replace('>', '\\>')
    val = val.replace('\x00', '\\00')
    if val[0] in ('#', ' '):
        val = '\\' + val
    if val[-1] == ' ':
        val = val[:-1] + '\\ '
    return val


def p_track_start(t):
    """track_flag : START
                  | START TIMESTAMP"""
    from audiotools.toc import TOCFlag_START
    if len(t) == 2:
        t[0] = TOCFlag_START()
    else:
        from fractions import Fraction
        t[0] = TOCFlag_START(Fraction(t[2], 75))


@classmethod
def RegisterHelpers(cls, helper_classes):
    """Registers helper classes.

    The helper classes are identified based on their lower case name.

    Args:
      helper_classes (list[type]): class objects of the argument helpers.

    Raises:
      KeyError: if helper class is already set for the corresponding name.
    """
    for helper_class in helper_classes:
        cls.RegisterHelper(helper_class)


def _try_convert_str_to_float(value, label):
    """
  Try to convert input value to float value.
  """
    try:
        return float(value)
    except Exception:
        msg = 'Invalid parameter: {} cannot cast string to float.'.format(label
            )
        raise ValueError(msg)


def get_adbtunnel_stop_timeout():
    """
    Return adbtunnel stop timeout in seconds
    """
    return 10


@classmethod
def load_fasttext_format(cls, model_file, encoding='utf8'):
    """
        Load the input-hidden weight matrix from the fast text output files.

        Note that due to limitations in the FastText API, you cannot continue training
        with a model loaded this way, though you can query for word similarity etc.

        `model_file` is the path to the FastText output files.
        FastText outputs two model files - `/path/to/model.vec` and `/path/to/model.bin`

        Expected value for this example: `/path/to/model` or `/path/to/model.bin`,
        as gensim requires only `.bin` file to load entire fastText model.

        """
    model = cls()
    if not model_file.endswith('.bin'):
        model_file += '.bin'
    model.file_name = model_file
    model.load_binary_data(encoding=encoding)
    return model


def pre_upgrade():
    """  Run pre-upgrade checks (optional). """


def densenet_params(model_name):
    """ Map densenet_pytorch model name to parameter coefficients. """
    params_dict = {'densenet121': (32, 64, 224), 'densenet161': (48, 96,
        224), 'densenet169': (32, 64, 224), 'densenet201': (32, 64, 224)}
    return params_dict[model_name]


def azion_cdn(cdn_name):
    """
        Create default CDN attributes.
    """
    return {'name': cdn_name, 'origin_address': 'domain.{}'.format(cdn_name
        ), 'cname_access_only': True, 'cname': ['www1.{}'.format(cdn_name)],
        'delivery_protocol': 'http', 'cdn_cache_settings': 'override',
        'cdn_cache_settings_minimum_ttl': 2592000, 'origin_protocol_policy':
        'preserve'}


def foreground_origin():
    """Return the original object of FHIR model that is proxied!"""


def splitSource(source):
    """
        splits a (text) file with several entries
        returns a list of those entries
        """


def searchMemberData(search_param, search_term, attributes=()):
    """ Return a sequence of mappings of memberdata for the given criteria.

        o 'search_param' is the property ID to be searched.

        o 'search_term' is the property value to be searched.

        o 'attributes', if passed, controls the keys in the returned mappings;
          by default the returned keys are 'username' and 'email'.

        o ???:  that default is silly;  if it is truly needed, then it should
          be the default value of the 'attributes' argument.

        o Permission:  Private (Python only)
        """


def _get_objects(source):
    """
    Returns a list of objects

    If source is lavavu.Viewer() list contains all objects
    If source is lavavu.Object() list contains that single object
    """
    if source.__class__.__name__ == 'Viewer':
        return source.objects.list
    elif not isinstance(source, list):
        return [source]
    else:
        return source


def HEDH_Taborek(P, Pc, Te=None, q=None):
    """Calculates heat transfer coefficient for a evaporator operating
    in the nucleate boiling regime according to Taborek (1986)
    as described in [1]_ and as presented in [2]_. Modification of [3]_.

    Either heat flux or excess temperature is required.

    With `Te` specified:

    .. math::
        h = \\left(0.00417P_c^{0.69} \\Delta Te^{0.7}\\left[2.1P_r^{0.27} +
        \\left(9 + (1-Pr^2)^{-1}\\right)P_r^2 \\right]\\right)^{1/0.3}

    With `q` specified:

    .. math::
        h = 0.00417P_c^{0.69} q^{0.7}\\left[2.1P_r^{0.27} + \\left(9 + (1-Pr^2
        )^{-1}\\right)P_r^2\\right]

    Parameters
    ----------
    P : float
        Saturation pressure of fluid, [Pa]
    Pc : float
        Critical pressure of fluid, [Pa]
    Te : float, optional
        Excess wall temperature, [K]
    q : float, optional
        Heat flux, [W/m^2]

    Returns
    -------
    h : float
        Heat transfer coefficient [W/m^2/K]

    Notes
    -----
    Example is from [3]_ and matches to within the error of the algebraic
    manipulation rounding.

    Examples
    --------
    >>> HEDH_Taborek(Te=16.2, P=310.3E3, Pc=2550E3)
    1397.272486525486

    References
    ----------
    .. [1] Schlünder, Ernst U, and International Center for Heat and Mass
       Transfer. Heat Exchanger Design Handbook. Washington:
       Hemisphere Pub. Corp., 1987.
    .. [2] Mostinsky I. L.: "Application of the rule of corresponding states
       for the calculation of heat transfer and critical heat flux,"
       Teploenergetika 4:66, 1963 English Abstr. Br Chem Eng 8(8):586, 1963
    .. [3] Serth, R. W., Process Heat Transfer: Principles,
       Applications and Rules of Thumb. 2E. Amsterdam: Academic Press, 2014.
    """
    Pr = P / Pc
    if Te:
        return (0.00417 * (Pc / 1000.0) ** 0.69 * Te ** 0.7 * (2.1 * Pr **
            0.27 + (9 + 1.0 / (1 - Pr ** 2)) * Pr ** 2)) ** (1 / 0.3)
    elif q:
        return 0.00417 * (Pc / 1000.0) ** 0.69 * q ** 0.7 * (2.1 * Pr **
            0.27 + (9 + 1.0 / (1 - Pr ** 2)) * Pr ** 2)
    else:
        raise Exception('Either q or Te is needed for this correlation')


def end():
    """Return whether the current position is the last position
        """


def _rehydrate_skeleton_class(skeleton_class, class_dict):
    """Put attributes from `class_dict` back on `skeleton_class`.

    See CloudPickler.save_dynamic_class for more info.
    """
    registry = None
    for attrname, attr in class_dict.items():
        if attrname == '_abc_impl':
            registry = attr
        else:
            setattr(skeleton_class, attrname, attr)
    if registry is not None:
        for subclass in registry:
            skeleton_class.register(subclass)
    return skeleton_class


def convert_scale(value, value_scale, target_scale, round_digits=4):
    """Convert a value to a different scale."""
    return round(value * target_scale / value_scale, round_digits)


def deny_permission_to_role(permission_id, role_id):
    """Deny the permission to the role
        """


def show_header(**header):
    """Display a HTTP-style header on the command-line."""
    print('%s: %s' % ('Now', header['now']))
    print('%s: %s' % ('Stop-Name', header['name']))
    print('%s: %s' % ('Stop-ID', header.get('id', None)))
    print('')


def _unpack_index(i):
    """Unpack index and return exactly four elements.

    If index is more shallow than 4, return None for trailing
    dimensions. If index is deeper than 4, raise a KeyError.

    """
    if len(i) > 4:
        raise KeyError(
            'Tried to index history with {} indices but only 4 indices are possible.'
            .format(len(i)))
    i_e, k_e, i_b, k_b = i + tuple([None] * (4 - len(i)))
    return i_e, k_e, i_b, k_b


@classmethod
def get_type_of_counterparties(cls):
    """
        Method for fetching info about types of counterparties.

        :example:
            ``Common.get_type_of_counterparties()``
        :return:
            dictionary with info about types of counterparties
        :rtype:
            dict
        """
    req = cls.send(method='getTypesOfCounterparties')
    return req


@classmethod
def get_assets(cls, lat, lon, begin=None, end=None):
    """
        Returns date and ids of flyovers

        Args:
            lat: latitude float
            lon: longitude float
            begin: date instance
            end: date instance

        Returns:
            json
        """
    instance = cls('planetary/earth/assets')
    filters = {'lat': lat, 'lon': lon, 'begin': begin, 'end': end}
    return instance.get_resource(**filters)


def do_batch(value, linecount, fill_with=None):
    """
    A filter that batches items. It works pretty much like `slice`
    just the other way round. It returns a list of lists with the
    given number of items. If you provide a second parameter this
    is used to fill up missing items. See this example:

    .. sourcecode:: html+jinja

        {%- for row in items|batch(3, ' ') %}

          {%- for column in row %}
            {{ column }}
          {%- endfor %}

        {%- endfor %}

    """
    tmp = []
    for item in value:
        if len(tmp) == linecount:
            yield tmp
            tmp = []
        tmp.append(item)
    if tmp:
        if fill_with is not None and len(tmp) < linecount:
            tmp += [fill_with] * (linecount - len(tmp))
        yield tmp


@classmethod
def concatenate(cls, objects, **kwargs):
    """Concatenate objects to get object that would be recieved if
        the concatenated serialization were deserialized.

        Args:
            objects (list): Objects to be concatenated.
            **kwargs: Additional keyword arguments are ignored.

        Returns:
            list: Set of objects that results from concatenating those provided.

        """
    return objects


@classmethod
def find_son_sysorg(cls, org_code):
    """
        根据机构编号获取本机构旗下所有机构信息
        :param org_code:
        :return:
        """
    return cls.objects(org_code__startswith=org_code, status__in=[0, 1]
        ).order_by('org_code').all()


@classmethod
def make(cls, poetry):
    """Build a wheel in the dist/ directory, and optionally upload it."""
    cls.make_in(poetry)


def find_fn(obj, names, name):
    """Find function in from list of names, raise ValueError not found."""
    for name in names:
        fn = getattr(obj, name, None)
        if fn:
            return fn
    raise ValueError('cannot find {} function for {}'.format(name, obj))


def took_off(info):
    """
        Process 'user took off' event.

        Input:
        `info`  # An object with information about event's time, user's
                # callsign, aircraft and position on map.
        """


@classmethod
def from_data(cls, data, labels=None, feature_names=None, label_names=None,
    static=True):
    """
    Converts two arrays or a sparse matrix data and its associated label array to Dataset.

    Parameters
    ----------
    data : array or scipy 2-D sparse matrix of shape [n_samples, n_features]
    labels : array of shape [n_samples], optional
    feature_names : array of shape [n_features], optional
    label_names : array of shape [n_labels], optional
    """
    if hasattr(data, 'todense'):
        return cls.from_matrix(data, labels, feature_names, label_names, static
            )
    else:
        return cls.from_array(data, labels, feature_names, label_names, static)


def _formDirected(g, match):
    """Form directed graph D from G and matching M.

    Parameters
    ----------
    g :
        Undirected bipartite graph. Nodes are separated by their
        'bipartite' attribute.
    match :
        List of edges forming a matching of `g`.

    Returns
    -------
    networkx.DiGraph
	    Directed graph, with edges in `match` pointing from set-0
	    (bipartite attribute==0) to set-1 (bipartite attrbiute==1), and
	    the other edges in `g` but not in `match` pointing from set-1 to
	    set-0.

    """
    import networkx as nx
    d = nx.DiGraph()
    for ee in g.edges():
        if ee in match or (ee[1], ee[0]) in match:
            if g.nodes[ee[0]]['bipartite'] == 0:
                d.add_edge(ee[0], ee[1])
            else:
                d.add_edge(ee[1], ee[0])
        elif g.nodes[ee[0]]['bipartite'] == 0:
            d.add_edge(ee[1], ee[0])
        else:
            d.add_edge(ee[0], ee[1])
    return d


def write_outflow(file_name, outflow):
    """Write the outflow values to a file.
    """
    fobj = open(file_name, 'w')
    header = outflow.keys()
    for head in header:
        fobj.write('%20s' % head)
    fobj.write('\n')
    for lineno in range(len(outflow[head])):
        for head in header:
            fobj.write('%20.17f' % outflow[head][lineno])
        fobj.write('\n')


def sys_encoding():
    """Charset to use for --file <path>|- (stdin)"""
    return 'utf8'


def rootDomain():
    """
        Получить корневой домен партнера.

        @return: Deferred, корневой домен (L{IDomain})
        @rtype: C{twisted.internet.defer.Deferred}
        """


@staticmethod
def p_value_table_description_list(p):
    """value_table_description_list : value_table_description
                                        | value_table_description value_table_description_list"""
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


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 add_mixin_to_class(basecls, mixins):
    """
    Given a class, adds the provided mixin classes as base classes and gives a new class

    :param Type basecls: An initial class to generate a new class from
    :param List[Type] mixins: A list of mixins to add as base classes
    :return: A new class with the provided mixins as base classes
    :rtype: Type[basecls, *mixins]
    """
    if not any(mixins):
        return basecls
    base_dict = basecls.__dict__.copy()
    class_tuple = basecls,
    for mixin in mixins:
        if not mixin:
            continue
        mixin_dict = mixin.__dict__.copy()
        base_dict.update(mixin_dict)
        class_tuple = class_tuple + (mixin,)
    base_dict.update(basecls.__dict__)
    return type(basecls.__name__, class_tuple, base_dict)


def rot32(w, nLeft):
    """ Rotate 32-bit word left by nLeft or right by -nLeft
        without creating a Python long.
        Timing depends on nLeft but not on w.
    """
    nLeft &= 31
    if nLeft == 0:
        return w
    RRR = (w >> 1 & 2147483647) >> 31 - nLeft
    sLLLLLL = -(1 << 31 - nLeft & w) | 2147483647 >> nLeft & w
    return RRR | sLLLLLL << nLeft


def set_close_exec(fd):
    """
    exec functions (e.g. subprocess.Popen) by default force the child
    process to inherit all file handles which can result in stuck
    connections and unacknowledged messages. Setting FD_CLOEXEC forces
    the handles to be closed first.
    """
    try:
        import fcntl
        flags = fcntl.fcntl(fd, fcntl.F_GETFD)
        fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
    except ImportError:
        pass


def default(inst):
    """Default routine to be applied when loading data.

    Parameters
    -----------
    inst : (pysat.Instrument)
        Instrument class object

    Note
    ----
        Removes ICON preamble on variable names.

    """
    import pysat.instruments.icon_ivm as icivm
    inst.tag = 'level_2'
    icivm.remove_icon_names(inst, target='ICON_L2_EUV_Daytime_OP_')


def unload_fixture(apps, schema_editor):
    """Brutally deleting all entries for this model..."""
    TimeSeriesDataType = apps.get_model('fitapp', 'TimeSeriesDataType')
    TimeSeriesDataType.objects.all().delete()


def run_hooks(obj, hooks, *args):
    """Run each function in `hooks' with args"""
    for hook in hooks:
        if hook(obj, *args):
            return True
        pass
    return False


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

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

        A hypothetical configuration would look like:

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

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

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

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

        """
    return cls(**local_config)


def key_description(character):
    """generate a readable description for a key"""
    ascii_code = ord(character)
    if ascii_code < 32:
        return 'Ctrl+{:c}'.format(ord('@') + ascii_code)
    else:
        return repr(character)


def normalize(text, replacement_tuples=[]):
    """Normalize Arabic text by replacing complex characters by simple ones.

    Args:
        text (str): the string that needs to be normalized
        replacement_tuples (list of tuple pairs): (character, replacement)

    Examples:
        >>> normalize('AlphaBet', [("A", "a"), ("B", "b")])
        'alphabet'
    """
    for char, repl in replacement_tuples:
        text = text.replace(char, repl)
    return text


@staticmethod
def homogenize_types(df, groupby_cols):
    """Converting all GROUPBY columns to strings

        When grouping by a numeric (say FLOAT) column, pydruid returns
        strings in the dataframe. This creates issues downstream related
        to having mixed types in the dataframe

        Here we replace None with <NULL> and make the whole series a
        str instead of an object.
        """
    for col in groupby_cols:
        df[col] = df[col].fillna('<NULL>').astype('unicode')
    return df


def create_flag_file(flag_file):
    """
    Creates a flag file to indicate read/write status of data file
    """
    with open(flag_file, 'w') as f:
        f.write('close')
    return None


def _mult_gf2(f1, f2):
    """Multiply two polynomials in GF(2)"""
    if f2 > f1:
        f1, f2 = f2, f1
    z = 0
    while f2:
        if f2 & 1:
            z ^= f1
        f1 <<= 1
        f2 >>= 1
    return z


def path_open(filepath: str=''):
    """Open a path in a file browser

    :param filepath: filepath
    :type filepath: str
    """
    pass


def assert_string_data(value: str) ->None:
    """Asserts value is string type."""
    assert isinstance(value, str
        ), f'Input value type must be string. Actual type: {type(value)}, value: {value}'


@classmethod
def from_datetime(cls, dt):
    """
        Constructs a :class:`mw.Timestamp` from a :class:`datetime.datetime`.

        :Parameters:
            dt : :class:`datetime.datetime``
                A datetime.

        :Returns:
            :class:`mw.Timestamp`
        """
    time_struct = dt.timetuple()
    return cls.from_time_struct(time_struct)


def change_identifiers(datadf, split_dict):
    """Change the dataset identifiers based on the names in the dictionary."""
    for rid, name in split_dict.items():
        datadf.loc[datadf['runIDs'] == rid, 'dataset'] = name


def provider_parser(subparser):
    """Configure provider parser for NSOne"""
    subparser.add_argument('--auth-token', help=
        'specify token for authentication')


def add_inbox(username):
    """Add an inbox for the user `username`. Returns the inbox."""


def integer_repr(bin_str, fixed_width=False):
    """integer_repr(bin_str, fixed_width=False)

    Converts a binary representation to its integer number.

    Examples
    --------

    >>> integer_repr(b'11')
    3
    >>> integer_repr(b'-11')
    -3
    >>> integer_repr(b'0011')
    3

    The two's complement is returned when negative number with fixed width
    representation is given:

    >>> integer_repr(b'1101', fixed_width=True)
    -3
    >>> integer_repr(b'1101', fixed_width=False)
    13

    """
    if fixed_width:
        assert bin_str[:1] != b'-', 'invalid fixed-width binary representation'
        num = int(bin_str, 2)
        if bin_str[:1] == b'1':
            num -= 2 ** len(bin_str)
        return num
    else:
        return int(bin_str, 2)


def _pandas_in_schemas(schemas):
    """
    Check if any schema contains pandas metadata
    """
    has_pandas = False
    for schema in schemas:
        if schema.metadata and b'pandas' in schema.metadata:
            has_pandas = True
    return has_pandas


def resetForm():
    """Reset any cached data because underlying content may have changed
        """


def set_doc_string_generator(func):
    """Set doc string generator function

    :param callable func:
        Callable which takes a GIInfoStruct and returns documentation for it.
    """
    global _generate_doc_string_func
    _generate_doc_string_func = func


@classmethod
def match_with_complete_solution_string(cls, solution_stack_list,
    complete_solution_stack_name):
    """
        Method returns a SolutionStack object representing the `complete_solution_stack_name`
        if it is found in `solution_stack_list`

        :param solution_stack_list: A list of SolutionStack objects to search in
        :param complete_solution_stack_name: The complete name of a solution stack as returned
                by `eb platform --list verbose`

        :return: A SolutionStack object representing the input solution stack
        """
    for solution_stack in solution_stack_list:
        if solution_stack.name.lower() == complete_solution_stack_name.lower():
            return solution_stack


@classmethod
def format_real(cls, num):
    """Format a float in fixed mode"""
    return '%.*f' % (cls.digits, num)


def set_proxy_ca_cert(filename):
    """Set the current sessions proxy CA cert file
    """
    global __peach_ca_cert
    __peach_ca_cert = filename


def say_hello(to):
    """Say hello to somebody"""
    return f'Hello {to}!'


def guess_contains_ncurses(lines):
    """Tries to determine if a file includes Ncurses
    """
    for line in lines:
        if '_nc_first_name' in line:
            return 1
        if '_nc_infotocap' in line:
            return 1
        if 'if NCURSES_XNAMES' in line:
            return 1
    return 0


def remove_suffix(string):
    """Removes suffixes

          Args:
              string:str
          Returns:
              returns str
          """
    suffixes = ['Esq', 'Ii', 'Iii', 'Iiii', 'Iv', 'Jnr', 'Jr', 'Sr']
    string = string.replace(' ', '')
    string = string.replace('.', '')
    string = string.replace(',', '')
    for suffix in suffixes:
        if string.endswith(suffix):
            string = string[:-len(suffix)]
            return string
    return string


def parse_keqv_list(l):
    """Parse list of key=value strings where keys are not duplicated."""
    parsed = {}
    for elt in l:
        k, v = elt.split('=', 1)
        if v[0] == '"' and v[-1] == '"':
            v = v[1:-1]
        parsed[k] = v
    return parsed


def _add_doc(func, doc):
    """Add documentation to a function."""
    func.__doc__ = doc


def create_error(msg, input_id=''):
    """
    Format an error response for validation of integration instances and actions

    Args:
        msg (str/unicode): Message to present to the user
        input_id (str): The environment variable name (what the variable is called in the descriptor and in inputs.py)

    Returns:
        (dict): Message and field ID to return to the user

    """
    return {'message': msg, 'inputId': input_id}


def MissingDependencyError(Exception):
    """Optional dependency not available."""
    pass


def add(a, b):
    """TODO(smarsu): Separate bias_add() from add()."""
    return a + b


@classmethod
def is_datasource_for(cls, **kwargs):
    """
        Determines if header corresponds to an NOAA indices timeseries.
        """
    if kwargs.get('source', ''):
        return kwargs.get('source', '').lower().startswith(cls._source)


def set(name, value):
    """Sets a variable to value

        :param name: string, variable name
        :param value: value of the key
        """


def ndof_all():
    """Pan and rotate the view with the 3D mouse

    """
    pass


def is_child_uri(parentUri, childUri):
    """Return True, if childUri is a child of parentUri.

    This function accounts for the fact that '/a/b/c' and 'a/b/c/' are
    children of '/a/b' (and also of '/a/b/').
    Note that '/a/b/cd' is NOT a child of 'a/b/c'.
    """
    return parentUri and childUri and childUri.rstrip('/').startswith(
        parentUri.rstrip('/') + '/')


def set_ec(ec):
    """
    Sets the exit code of the program, if an exit code higher or equal than this is set, this does nothing. This
    makes EXIT_ERROR override EXIT_WARNING, etc..

    ec: exit code to set
    """
    global exit_code
    exit_code = max(exit_code, ec)
    return exit_code


@classmethod
def createActiveMask(cls, range_string):
    """
        Will create a BoolVector instance with the values from @range_string.

        The range_string input should be of the type "1,3-5,9,17",
        i.e. integer values separated by commas, and dashes to
        represent ranges. If the input string contains ANY invalid
        characters the returned active list will be empty:

           "1,4-7,10"  =>  {F,T,F,F,T,T,T,T,F,F,T}
           "1,4-7,10X" =>  {}

        The empty list will evaluate to false
        @rtype: BoolVector
        """
    return cls._create_active_mask(range_string)


def dicts_are_the_same(a, b):
    """Compare two dicts, ``a`` and ``b`` and return ``True`` if they contain
      exactly the same items.

      Ref: http://stackoverflow.com/a/17095033
    """
    return not len(set(a.items()) ^ set(b.items()))


def get_run(arn=None):
    """
    Gets information about a run.
    See also: AWS API Documentation

    Examples
    The following example gets information about a specific test run.
    Expected Output:

    :example: response = client.get_run(
        arn='string'
    )

    :type arn: string
    :param arn: [REQUIRED]
            The run's ARN.

    :rtype: dict
    :return: {
        'run': {
            'arn': 'string',
            'name': 'string',
            'type': 'BUILTIN_FUZZ'|'BUILTIN_EXPLORER'|'APPIUM_JAVA_JUNIT'|'APPIUM_JAVA_TESTNG'|'APPIUM_PYTHON'|'APPIUM_WEB_JAVA_JUNIT'|'APPIUM_WEB_JAVA_TESTNG'|'APPIUM_WEB_PYTHON'|'CALABASH'|'INSTRUMENTATION'|'UIAUTOMATION'|'UIAUTOMATOR'|'XCTEST'|'XCTEST_UI',
            'platform': 'ANDROID'|'IOS',
            'created': datetime(2015, 1, 1),
            'status': 'PENDING'|'PENDING_CONCURRENCY'|'PENDING_DEVICE'|'PROCESSING'|'SCHEDULING'|'PREPARING'|'RUNNING'|'COMPLETED'|'STOPPING',
            'result': 'PENDING'|'PASSED'|'WARNED'|'FAILED'|'SKIPPED'|'ERRORED'|'STOPPED',
            'started': datetime(2015, 1, 1),
            'stopped': datetime(2015, 1, 1),
            'counters': {
                'total': 123,
                'passed': 123,
                'failed': 123,
                'warned': 123,
                'errored': 123,
                'stopped': 123,
                'skipped': 123
            },
            'message': 'string',
            'totalJobs': 123,
            'completedJobs': 123,
            'billingMethod': 'METERED'|'UNMETERED',
            'deviceMinutes': {
                'total': 123.0,
                'metered': 123.0,
                'unmetered': 123.0
            },
            'networkProfile': {
                'arn': 'string',
                'name': 'string',
                'description': 'string',
                'type': 'CURATED'|'PRIVATE',
                'uplinkBandwidthBits': 123,
                'downlinkBandwidthBits': 123,
                'uplinkDelayMs': 123,
                'downlinkDelayMs': 123,
                'uplinkJitterMs': 123,
                'downlinkJitterMs': 123,
                'uplinkLossPercent': 123,
                'downlinkLossPercent': 123
            }
        }
    }

    :returns:
    ANDROID: The Android platform.
    IOS: The iOS platform.

    """
    pass


def paths_whitelist(runner, params):
    """ Replace current list of whitelisted paths
    """
    params = params[0]
    runner.set_paths_whitelist(params)
    return {'status': True}


def recast_columns(columns):
    """Cast columns to Characteristics and Parameter Values

    :param columns: String list of columns to cast
    :return: The casted columns as a list
    """
    casting_map = {'Material Type': 'Characteristics[Material Type]',
        'Date': 'Parameter Value[Date]', 'Performer':
        'Parameter Value[Performer]'}
    for k, v in casting_map.items():
        columns = list(map(lambda x: v if x == k else x, columns))
    return columns


def option_not_exist_msg(option_name, existing_options):
    """ Someone is referencing an option that is not available in the current package
    options
    """
    result = ["'options.%s' doesn't exist" % option_name]
    result.append('Possible options are %s' % existing_options or 'none')
    return '\n'.join(result)


def _add_volumes(bold_file, bold_cut_file, skip_vols):
    """Prepend skip_vols from bold_file onto bold_cut_file."""
    import nibabel as nb
    import numpy as np
    from nipype.utils.filemanip import fname_presuffix
    if skip_vols == 0:
        return bold_cut_file
    bold_img = nb.load(bold_file)
    bold_cut_img = nb.load(bold_cut_file)
    bold_data = np.concatenate((bold_img.dataobj[(...), :skip_vols],
        bold_cut_img.dataobj), axis=3)
    out = fname_presuffix(bold_cut_file, suffix='_addnonsteady')
    bold_img.__class__(bold_data, bold_img.affine, bold_img.header
        ).to_filename(out)
    return out


def __call__(input_stream, env):
    """Create a request object to handle input."""


@classmethod
def from_stream(cls, stream, marker_code, offset):
    """
        Return an |_App0Marker| instance for the APP0 marker at *offset* in
        *stream*.
        """
    segment_length = stream.read_short(offset)
    density_units = stream.read_byte(offset, 9)
    x_density = stream.read_short(offset, 10)
    y_density = stream.read_short(offset, 12)
    return cls(marker_code, offset, segment_length, density_units,
        x_density, y_density)


def move_vol_geom(geom, pos, is_relative=False):
    """Moves center of volume geometry to new position.

    :param geom: Input volume geometry
    :type geom: :class:`dict`
    :param pos: Tuple (x,y[,z]) for new position, with the center of the image at (0,0[,0])
    :type pos: :class:`tuple`
    :param is_relative: Whether new position is relative to the old position
    :type is_relative: :class:`bool`
    :returns: :class:`dict` -- Volume geometry with the new center
    """
    ret_geom = geom.copy()
    ret_geom['option'] = geom['option'].copy()
    if not is_relative:
        ret_geom['option']['WindowMinX'] = -geom['GridColCount'] / 2.0
        ret_geom['option']['WindowMaxX'] = geom['GridColCount'] / 2.0
        ret_geom['option']['WindowMinY'] = -geom['GridRowCount'] / 2.0
        ret_geom['option']['WindowMaxY'] = geom['GridRowCount'] / 2.0
        if len(pos) > 2:
            ret_geom['option']['WindowMinZ'] = -geom['GridSliceCount'] / 2.0
            ret_geom['option']['WindowMaxZ'] = geom['GridSliceCount'] / 2.0
    ret_geom['option']['WindowMinX'] += pos[0]
    ret_geom['option']['WindowMaxX'] += pos[0]
    ret_geom['option']['WindowMinY'] += pos[1]
    ret_geom['option']['WindowMaxY'] += pos[1]
    if len(pos) > 2:
        ret_geom['option']['WindowMinZ'] += pos[2]
        ret_geom['option']['WindowMaxZ'] += pos[2]
    return ret_geom


def worker(queue, context, pool):
    """
    Run work items from the queue until the sentinal
    None value is hit
    """
    while True:
        work, args, kwargs = queue.get(True)
        if not work:
            break
        kwargs.update(context)
        try:
            work(*args, **kwargs)
        except:
            import sys
            pool.raise_exception(sys.exc_info())
            break


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

    The ".dev0" means dirty.

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


@classmethod
def from_list(cls, values):
    """Construct a wrench from a list of 6 :obj:`float` values.

        Parameters
        ----------
        values : :obj:`list` of :obj:`float`
            The list of 6 values representing a wrench.

        Returns
        -------
        :class:`Wrench`
            The constructed wrench.

        Examples
        --------
        >>> w = Wrench.from_list([1, 2, 3, 0.1, 0.2, 0.3])
        """
    force = values[0:3]
    torque = values[3:6]
    return cls(force, torque)


def type_object_attrgetter(obj, attr, *defargs):
    """
    This implements an improved attrgetter for type objects (i.e. classes)
    that can handle class attributes that are implemented as properties on
    a metaclass.

    Normally `getattr` on a class with a `property` (say, "foo"), would return
    the `property` object itself.  However, if the class has a metaclass which
    *also* defines a `property` named "foo", ``getattr(cls, 'foo')`` will find
    the "foo" property on the metaclass and resolve it.  For the purposes of
    autodoc we just want to document the "foo" property defined on the class,
    not on the metaclass.

    For example::

        >>> class Meta(type):
        ...     @property
        ...     def foo(cls):
        ...         return 'foo'
        ...
        >>> class MyClass(metaclass=Meta):
        ...     @property
        ...     def foo(self):
        ...         ""\"Docstring for MyClass.foo property.""\"
        ...         return 'myfoo'
        ...
        >>> getattr(MyClass, 'foo')
        'foo'
        >>> type_object_attrgetter(MyClass, 'foo')
        <property at 0x...>
        >>> type_object_attrgetter(MyClass, 'foo').__doc__
        'Docstring for MyClass.foo property.'

    The last line of the example shows the desired behavior for the purposes
    of autodoc.
    """
    for base in obj.__mro__:
        if attr in base.__dict__:
            if isinstance(base.__dict__[attr], property):
                return base.__dict__[attr]
            break
    return getattr(obj, attr, *defargs)


def get_resnik_score(hpo_graph, proband_1, proband_2):
    """ Calculate the similarity in HPO terms between terms for two probands.

    This runs through the pairs of HPO terms from the two probands and finds
    the information content for the most informative common ancestor for each
    pair. We return the largest of these IC scores, known as the maxIC.

    Reference:
        Resnik, J Artif Intell Res (1999), 11:95-130.

    Args:
        hpo_graph: ICSimilarity object for the HPO term graph, with
            information on how many times each term has been used across all
            probands.
        proband_1: list of HPO terms for one proband
        proband_2: list of HPO terms for the other proband

    Returns:
        A score for how similar the terms are between the two probands.
    """
    ic = []
    for term_1 in proband_1:
        for term_2 in proband_2:
            ic.append(hpo_graph.get_most_informative_ic(term_1, term_2))
    return max(ic)


def similar_values_iter(v1, v2, e=1e-06):
    """Return True if iterables v1 and v2 are nearly the same."""
    if v1 == v2:
        return True
    for v1, v2 in zip(v1, v2):
        if v1 != v2 and abs(v1 - v2) / max(abs(v1), abs(v2)) > e:
            return False
    return True


def fmodifier_copy():
    """Copy the F-Modifier(s) of the active NLA-Strip

    """
    pass