<commit_before># Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from decorator import decorator
import inspect
import time

import netifaces

from shade import exc

def _iterate_timeout(timeout, message, wait=2):
    """Iterate and raise an exception on timeout.

    This is a generator that will continually yield and sleep for
    wait seconds, and if the timeout is reached, will raise an exception
    with <message>.

    """

    start = time.time()
    count = 0
    while (timeout is None) or (time.time() < start + timeout):
        count += 1
        yield count
        time.sleep(wait)
    raise exc.OpenStackCloudTimeout(message)

def _filter_list(data, name_or_id, filters, name_key='name'):
    """Filter a list by name/ID and arbitrary meta data.

    :param list data:
        The list of dictionary data to filter. It is expected that
        each dictionary contains an 'id' and 'name'
        key if a value for name_or_id is given. The 'name' key can be
        overridden with the name_key parameter.
    :param string name_or_id:
        The name or ID of the entity being filtered.
    :param dict filters:
        A dictionary of meta data to use for further filtering. Elements
        of this dictionary may, themselves, be dictionaries. Example::

            {
              'last_name': 'Smith',
              'other': {
                  'gender': 'Female'
              }
            }
    :param string name_key:
        The name of the name key. Cinder wants display_name. Heat wants
        stack_name. Defaults to 'name'
    """
    if name_or_id:
        identifier_matches = []
        for e in data:
            e_id = str(e.get('id', None))
            e_name = e.get(name_key, None)
            if str(name_or_id) in (e_id, e_name):
                identifier_matches.append(e)
        data = identifier_matches

    if not filters:
        return data

    def _dict_filter(f, d):
        if not d:
            return False
        for key in f.keys():
            if isinstance(f[key], dict):
                if not _dict_filter(f[key], d.get(key, None)):
                    return False
            elif d.get(key, None) != f[key]:
                return False
        return True

    filtered = []
    for e in data:
        filtered.append(e)
        for key in filters.keys():
            if isinstance(filters[key], dict):
                if not _dict_filter(filters[key], e.get(key, None)):
                    filtered.pop()
                    break
            elif e.get(key, None) != filters[key]:
                filtered.pop()
                break
    return filtered

def _get_entity(func, name_or_id, filters):
    """Return a single entity from the list returned by a given method.

    :param callable func:
        A function that takes `name_or_id` and `filters` as parameters
        and returns a list of entities to filter.
    :param string name_or_id:
        The name or ID of the entity being filtered.
    :param dict filters:
        A dictionary of meta data to use for further filtering.
    """
    entities = func(name_or_id, filters)
    if not entities:
        return None
    if len(entities) > 1:
        raise exc.OpenStackCloudException(
            "Multiple matches found for %s" % name_or_id)
    return entities[0]

def normalize_keystone_services(services):
    """Normalize the structure of keystone services

    In keystone v2, there is a field called "service_type". In v3, it's
    "type". Just make the returned dict have both.

    :param list services: A list of keystone service dicts

    :returns: A list of normalized dicts.
    """
    ret = []
    for service in services:
        service_type = service.get('type', service.get('service_type'))
        new_service = {
            'id': service['id'],
            'name': service['name'],
            'description': service.get('description', None),
            'type': service_type,
            'service_type': service_type,
        }
        ret.append(new_service)
    return ret

def normalize_nova_secgroups(groups):
    """Normalize the structure of nova security groups

    This makes security group dicts, as returned from nova, look like the
    security group dicts as returned from neutron. This does not make them
    look exactly the same, but it's pretty close.

    :param list groups: A list of security group dicts.

    :returns: A list of normalized dicts.
    """
    return [{'id': g['id'],
             'name': g['name'],
             'description': g['description'],
             'security_group_rules': normalize_nova_secgroup_rules(g['rules'])
             } for g in groups]

def normalize_nova_secgroup_rules(rules):
    """Normalize the structure of nova security group rules

    Note that nova uses -1 for non-specific port values, but neutron
    represents these with None.

    :param list rules: A list of security group rule dicts.

    :returns: A list of normalized dicts.
    """
    return [{'id': r['id'],
             'direction': 'ingress',
             'ethertype': 'IPv4',
             'port_range_min':
                 None if r['from_port'] == -1 else r['from_port'],
             'port_range_max':
                 None if r['to_port'] == -1 else r['to_port'],
             'protocol': r['ip_protocol'],
             'remote_ip_prefix': r['ip_range'].get('cidr', None),
             'security_group_id': r['parent_group_id']
             } for r in rules]

def normalize_nova_floating_ips(ips):
    """Normalize the structure of Neutron floating IPs

    Unfortunately, not all the Neutron floating_ip attributes are available
    with Nova and not all Nova floating_ip attributes are available with
    Neutron.
    This function extract attributes that are common to Nova and Neutron
    floating IP resource.
    If the whole structure is needed inside shade, shade provides private
    methods that returns "original" objects (e.g. _nova_allocate_floating_ip)

    :param list ips: A list of Nova floating IPs.

    :returns:
        A list of normalized dicts with the following attributes::

        [
          {
            "id": "this-is-a-floating-ip-id",
            "fixed_ip_address": "192.0.2.10",
            "floating_ip_address": "198.51.100.10",
            "network": "this-is-a-net-or-pool-id",
            "attached": True,
            "status": "ACTIVE"
          }, ...
        ]

    """
    return [dict(
        id=ip['id'],
        fixed_ip_address=ip.get('fixed_ip'),
        floating_ip_address=ip['ip'],
        network=ip['pool'],
        attached=(ip.get('instance_id') is not None and
                  ip.get('instance_id') != ''),
        status='ACTIVE'  # In neutrons terms, Nova floating IPs are always
                         # ACTIVE
    ) for ip in ips]

def normalize_neutron_floating_ips(ips):
    """Normalize the structure of Neutron floating IPs

    Unfortunately, not all the Neutron floating_ip attributes are available
    with Nova and not all Nova floating_ip attributes are available with
    Neutron.
    This function extract attributes that are common to Nova and Neutron
    floating IP resource.
    If the whole structure is needed inside shade, shade provides private
    methods that returns "original" objects (e.g.
    _neutron_allocate_floating_ip)

    :param list ips: A list of Neutron floating IPs.

    :returns:
        A list of normalized dicts with the following attributes::

        [
          {
            "id": "this-is-a-floating-ip-id",
            "fixed_ip_address": "192.0.2.10",
            "floating_ip_address": "198.51.100.10",
            "network": "this-is-a-net-or-pool-id",
            "attached": True,
            "status": "ACTIVE"
          }, ...
        ]

    """
    return [dict(
        id=ip['id'],
        fixed_ip_address=ip.get('fixed_ip_address'),
        floating_ip_address=ip['floating_ip_address'],
        network=ip['floating_network_id'],
        attached=(ip.get('port_id') is not None and
                  ip.get('port_id') != ''),
        status=ip['status']
    ) for ip in ips]

def localhost_supports_ipv6():
    """Determine whether the local host supports IPv6

    We look for a default route that supports the IPv6 address family,
    and assume that if it is present, this host has globally routable
    IPv6 connectivity.
    """

    return netifaces.AF_INET6 in netifaces.gateways()['default']

def normalize_users(users):
    return [
        dict(
            id=user.get('id'),
            email=user.get('email'),
            name=user.get('name'),
            username=user.get('username'),
            default_project_id=user.get('default_project_id',
                                        user.get('tenantId')),
            domain_id=user.get('domain_id'),
            enabled=user.get('enabled'),
        ) for user in users
    ]

def valid_kwargs(*valid_args):
    # This decorator checks if argument passed as **kwargs to a function are
    # present in valid_args.
    #
    # Typically, valid_kwargs is used when we want to distinguish between
    # None and omitted arguments and we still want to validate the argument
    # list.
    #
    # Example usage:
    #
    # @valid_kwargs('opt_arg1', 'opt_arg2')
    # def my_func(self, mandatory_arg1, mandatory_arg2, **kwargs):
    #   ...
    #
    @decorator
    def func_wrapper(func, *args, **kwargs):
        argspec = inspect.getargspec(func)
        for k in kwargs:
            if k not in argspec.args[1:] and k not in valid_args:
                raise TypeError(
                    "{f}() got an unexpected keyword argument "
                    "'{arg}'".format(f=inspect.stack()[1][3], arg=k))
        return func(*args, **kwargs)
    return func_wrapper
<commit_msg>Add debug logging to iterate timeout<commit_after># Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from decorator import decorator
import inspect
import time

import netifaces

from shade import _log
from shade import exc

log = _log.setup_logging(__name__)

def _iterate_timeout(timeout, message, wait=2):
    """Iterate and raise an exception on timeout.

    This is a generator that will continually yield and sleep for
    wait seconds, and if the timeout is reached, will raise an exception
    with <message>.

    """

    start = time.time()
    count = 0
    while (timeout is None) or (time.time() < start + timeout):
        count += 1
        yield count
        log.debug('Waiting {wait} seconds'.format(wait=wait))
        time.sleep(wait)
    raise exc.OpenStackCloudTimeout(message)

def _filter_list(data, name_or_id, filters, name_key='name'):
    """Filter a list by name/ID and arbitrary meta data.

    :param list data:
        The list of dictionary data to filter. It is expected that
        each dictionary contains an 'id' and 'name'
        key if a value for name_or_id is given. The 'name' key can be
        overridden with the name_key parameter.
    :param string name_or_id:
        The name or ID of the entity being filtered.
    :param dict filters:
        A dictionary of meta data to use for further filtering. Elements
        of this dictionary may, themselves, be dictionaries. Example::

            {
              'last_name': 'Smith',
              'other': {
                  'gender': 'Female'
              }
            }
    :param string name_key:
        The name of the name key. Cinder wants display_name. Heat wants
        stack_name. Defaults to 'name'
    """
    if name_or_id:
        identifier_matches = []
        for e in data:
            e_id = str(e.get('id', None))
            e_name = e.get(name_key, None)
            if str(name_or_id) in (e_id, e_name):
                identifier_matches.append(e)
        data = identifier_matches

    if not filters:
        return data

    def _dict_filter(f, d):
        if not d:
            return False
        for key in f.keys():
            if isinstance(f[key], dict):
                if not _dict_filter(f[key], d.get(key, None)):
                    return False
            elif d.get(key, None) != f[key]:
                return False
        return True

    filtered = []
    for e in data:
        filtered.append(e)
        for key in filters.keys():
            if isinstance(filters[key], dict):
                if not _dict_filter(filters[key], e.get(key, None)):
                    filtered.pop()
                    break
            elif e.get(key, None) != filters[key]:
                filtered.pop()
                break
    return filtered

def _get_entity(func, name_or_id, filters):
    """Return a single entity from the list returned by a given method.

    :param callable func:
        A function that takes `name_or_id` and `filters` as parameters
        and returns a list of entities to filter.
    :param string name_or_id:
        The name or ID of the entity being filtered.
    :param dict filters:
        A dictionary of meta data to use for further filtering.
    """
    entities = func(name_or_id, filters)
    if not entities:
        return None
    if len(entities) > 1:
        raise exc.OpenStackCloudException(
            "Multiple matches found for %s" % name_or_id)
    return entities[0]

def normalize_keystone_services(services):
    """Normalize the structure of keystone services

    In keystone v2, there is a field called "service_type". In v3, it's
    "type". Just make the returned dict have both.

    :param list services: A list of keystone service dicts

    :returns: A list of normalized dicts.
    """
    ret = []
    for service in services:
        service_type = service.get('type', service.get('service_type'))
        new_service = {
            'id': service['id'],
            'name': service['name'],
            'description': service.get('description', None),
            'type': service_type,
            'service_type': service_type,
        }
        ret.append(new_service)
    return ret

def normalize_nova_secgroups(groups):
    """Normalize the structure of nova security groups

    This makes security group dicts, as returned from nova, look like the
    security group dicts as returned from neutron. This does not make them
    look exactly the same, but it's pretty close.

    :param list groups: A list of security group dicts.

    :returns: A list of normalized dicts.
    """
    return [{'id': g['id'],
             'name': g['name'],
             'description': g['description'],
             'security_group_rules': normalize_nova_secgroup_rules(g['rules'])
             } for g in groups]

def normalize_nova_secgroup_rules(rules):
    """Normalize the structure of nova security group rules

    Note that nova uses -1 for non-specific port values, but neutron
    represents these with None.

    :param list rules: A list of security group rule dicts.

    :returns: A list of normalized dicts.
    """
    return [{'id': r['id'],
             'direction': 'ingress',
             'ethertype': 'IPv4',
             'port_range_min':
                 None if r['from_port'] == -1 else r['from_port'],
             'port_range_max':
                 None if r['to_port'] == -1 else r['to_port'],
             'protocol': r['ip_protocol'],
             'remote_ip_prefix': r['ip_range'].get('cidr', None),
             'security_group_id': r['parent_group_id']
             } for r in rules]

def normalize_nova_floating_ips(ips):
    """Normalize the structure of Neutron floating IPs

    Unfortunately, not all the Neutron floating_ip attributes are available
    with Nova and not all Nova floating_ip attributes are available with
    Neutron.
    This function extract attributes that are common to Nova and Neutron
    floating IP resource.
    If the whole structure is needed inside shade, shade provides private
    methods that returns "original" objects (e.g. _nova_allocate_floating_ip)

    :param list ips: A list of Nova floating IPs.

    :returns:
        A list of normalized dicts with the following attributes::

        [
          {
            "id": "this-is-a-floating-ip-id",
            "fixed_ip_address": "192.0.2.10",
            "floating_ip_address": "198.51.100.10",
            "network": "this-is-a-net-or-pool-id",
            "attached": True,
            "status": "ACTIVE"
          }, ...
        ]

    """
    return [dict(
        id=ip['id'],
        fixed_ip_address=ip.get('fixed_ip'),
        floating_ip_address=ip['ip'],
        network=ip['pool'],
        attached=(ip.get('instance_id') is not None and
                  ip.get('instance_id') != ''),
        status='ACTIVE'  # In neutrons terms, Nova floating IPs are always
                         # ACTIVE
    ) for ip in ips]

def normalize_neutron_floating_ips(ips):
    """Normalize the structure of Neutron floating IPs

    Unfortunately, not all the Neutron floating_ip attributes are available
    with Nova and not all Nova floating_ip attributes are available with
    Neutron.
    This function extract attributes that are common to Nova and Neutron
    floating IP resource.
    If the whole structure is needed inside shade, shade provides private
    methods that returns "original" objects (e.g.
    _neutron_allocate_floating_ip)

    :param list ips: A list of Neutron floating IPs.

    :returns:
        A list of normalized dicts with the following attributes::

        [
          {
            "id": "this-is-a-floating-ip-id",
            "fixed_ip_address": "192.0.2.10",
            "floating_ip_address": "198.51.100.10",
            "network": "this-is-a-net-or-pool-id",
            "attached": True,
            "status": "ACTIVE"
          }, ...
        ]

    """
    return [dict(
        id=ip['id'],
        fixed_ip_address=ip.get('fixed_ip_address'),
        floating_ip_address=ip['floating_ip_address'],
        network=ip['floating_network_id'],
        attached=(ip.get('port_id') is not None and
                  ip.get('port_id') != ''),
        status=ip['status']
    ) for ip in ips]

def localhost_supports_ipv6():
    """Determine whether the local host supports IPv6

    We look for a default route that supports the IPv6 address family,
    and assume that if it is present, this host has globally routable
    IPv6 connectivity.
    """

    return netifaces.AF_INET6 in netifaces.gateways()['default']

def normalize_users(users):
    return [
        dict(
            id=user.get('id'),
            email=user.get('email'),
            name=user.get('name'),
            username=user.get('username'),
            default_project_id=user.get('default_project_id',
                                        user.get('tenantId')),
            domain_id=user.get('domain_id'),
            enabled=user.get('enabled'),
        ) for user in users
    ]

def valid_kwargs(*valid_args):
    # This decorator checks if argument passed as **kwargs to a function are
    # present in valid_args.
    #
    # Typically, valid_kwargs is used when we want to distinguish between
    # None and omitted arguments and we still want to validate the argument
    # list.
    #
    # Example usage:
    #
    # @valid_kwargs('opt_arg1', 'opt_arg2')
    # def my_func(self, mandatory_arg1, mandatory_arg2, **kwargs):
    #   ...
    #
    @decorator
    def func_wrapper(func, *args, **kwargs):
        argspec = inspect.getargspec(func)
        for k in kwargs:
            if k not in argspec.args[1:] and k not in valid_args:
                raise TypeError(
                    "{f}() got an unexpected keyword argument "
                    "'{arg}'".format(f=inspect.stack()[1][3], arg=k))
        return func(*args, **kwargs)
    return func_wrapper
<|endoftext|>


<commit_before>import struct
import sys
import gzip

"""
#define NAVDATA_PORT              5554
#define NAVDATA_HEADER            0x55667788
#define NAVDATA_BUFFER_SIZE       2048

    NAVDATA_DEMO_TAG = 0,
    NAVDATA_VISION_DETECT_TAG = 16,
    NAVDATA_IPHONE_ANGLES_TAG = 18,
    NAVDATA_CKS_TAG = 0xFFFF

NAVDATA_OPTION( navdata_time_t,           navdata_time            , NAVDATA_TIME_TAG             ) 1
NAVDATA_OPTION( navdata_raw_measures_t,   navdata_raw_measures    , NAVDATA_RAW_MEASURES_TAG     ) 2
NAVDATA_OPTION( navdata_phys_measures_t,  navdata_phys_measures   , NAVDATA_PHYS_MEASURES_TAG    ) 3
NAVDATA_OPTION( navdata_gyros_offsets_t,  navdata_gyros_offsets   , NAVDATA_GYROS_OFFSETS_TAG    ) 4
NAVDATA_OPTION( navdata_euler_angles_t,   navdata_euler_angles    , NAVDATA_EULER_ANGLES_TAG     ) 5
NAVDATA_OPTION( navdata_references_t,     navdata_references      , NAVDATA_REFERENCES_TAG       ) 6
NAVDATA_OPTION( navdata_trims_t,          navdata_trims           , NAVDATA_TRIMS_TAG            ) 7
NAVDATA_OPTION( navdata_rc_references_t,  navdata_rc_references   , NAVDATA_RC_REFERENCES_TAG    ) 8
NAVDATA_OPTION( navdata_pwm_t,            navdata_pwm             , NAVDATA_PWM_TAG              ) 9
NAVDATA_OPTION( navdata_altitude_t,       navdata_altitude        , NAVDATA_ALTITUDE_TAG         ) 10
NAVDATA_OPTION( navdata_vision_raw_t,     navdata_vision_raw      , NAVDATA_VISION_RAW_TAG       ) 11
NAVDATA_OPTION( navdata_vision_of_t,      navdata_vision_of       , NAVDATA_VISION_OF_TAG        ) 12
NAVDATA_OPTION( navdata_vision_t,         navdata_vision          , NAVDATA_VISION_TAG           ) 13
NAVDATA_OPTION( navdata_vision_perf_t ,   navdata_vision_perf     , NAVDATA_VISION_PERF_TAG      ) 14
NAVDATA_OPTION( navdata_trackers_send_t,  navdata_trackers_send   , NAVDATA_TRACKERS_SEND_TAG    ) 15
NAVDATA_OPTION( navdata_vision_detect_t,  navdata_vision_detect   , NAVDATA_VISION_DETECT_TAG    ) 16
NAVDATA_OPTION( navdata_watchdog_t  ,     navdata_watchdog        , NAVDATA_WATCHDOG_TAG         ) 17
NAVDATA_OPTION( navdata_adc_data_frame_t, navdata_adc_data_frame  , NAVDATA_ADC_DATA_FRAME_TAG   ) 18
NAVDATA_OPTION( navdata_video_stream_t,   navdata_video_stream    , NAVDATA_VIDEO_STREAM_TAG     ) 19
NAVDATA_OPTION( navdata_games_t,          navdata_games           , NAVDATA_GAMES_TAG            ) 20
NAVDATA_OPTION( navdata_pressure_raw_t,   navdata_pressure_raw    , NAVDATA_PRESSURE_RAW_TAG		 ) 21
NAVDATA_OPTION( navdata_magneto_t,       	navdata_magneto					, NAVDATA_MAGNETO_TAG					 ) 22
NAVDATA_OPTION( navdata_wind_speed_t,     navdata_wind_speed      , NAVDATA_WIND_TAG						 ) 23
NAVDATA_OPTION( navdata_kalman_pressure_t,navdata_kalman_pressure	, NAVDATA_KALMAN_PRESSURE_TAG	 ) 24
NAVDATA_OPTION( navdata_hdvideo_stream_t ,navdata_hdvideo_stream  , NAVDATA_HDVIDEO_STREAM_TAG	 ) 25
NAVDATA_OPTION( navdata_wifi_t           ,navdata_wifi            , NAVDATA_WIFI_TAG             ) 26

typedef struct _navdata_magneto_t {
  uint16_t   tag;
  uint16_t   size;

  int16_t   	mx;
  int16_t   	my;
  int16_t   	mz;
  vector31_t 	magneto_raw;       // magneto in the body frame, in mG
  vector31_t 	magneto_rectified;
  vector31_t 	magneto_offset;
  float32_t 	heading_unwrapped;
  float32_t 	heading_gyro_unwrapped;
  float32_t 	heading_fusion_unwrapped;
  char 			magneto_calibration_ok;
  uint32_t      magneto_state;
  float32_t 	magneto_radius;
  float32_t     error_mean;
  float32_t     error_var;

}_ATTRIBUTE_PACKED_ navdata_magneto_t;

"""
NAVDATA_DEMO_TAG = 0
NAVDATA_TIME_TAG = 1
NAVDATA_RAW_MEASURES_TAG = 2
NAVDATA_ALTITUDE_TAG = 10
NAVDATA_VISION_DETECT_TAG = 16
NAVDATA_IPHONE_ANGLES_TAG = 18
NAVDATA_MAGNETO_TAG = 22
NAVDATA_CKS_TAG = 0xFFFF

#    drone_state['navdata_bootstrap']    = _[1] >> 11 & 1 # Navdata bootstrap : (0) options sent in all or demo mode, (1) no navdata options sent */
#     drone_state['com_watchdog_mask']    = _[1] >> 30 & 1 # Communication Watchdog : (1) com problem, (0) Com is ok */

#    drone_state['command_mask']         = _[1] >>  6 & 1 # Control command ACK : (0) None, (1) one received */

def parseTimeTag( data, offset ):
  "uint32_t - the 11 most significant bits represents the seconds, and the 21 least significant bits are the microseconds."
# tag == NAVDATA_TIME_TAG:
  utime = struct.unpack_from("I", data, offset+4)[0]
  assert utime & (1<<20) == 0, str( (hex(utime), header[2]) )
  return (utime >> 21) + (utime & 0xFFFFF)/1000000.0

def parseDemoTag( data, offset ):
  values = struct.unpack_from("IIfffifff", data, offset+4)
  values = dict(zip(['ctrl_state', 'battery', 'theta', 'phi', 'psi', 'altitude', 'vx', 'vy', 'vz'], values))
  values['ctrl_state'] >>= 16
  return values

def parseVisionDetectTag( data, offset ):
  "tag == NAVDATA_VISION_DETECT_TAG"
  countTypes = struct.unpack_from("IIIII", data, offset+4)
  x = struct.unpack_from("IIII", data, offset+4+20)
  y = struct.unpack_from("IIII", data, offset+4+36)
  height = struct.unpack_from("IIII", data, offset+4+52)
  width = struct.unpack_from("IIII", data, offset+4+68)
  dist = struct.unpack_from("IIII", data, offset+4+84)
  oriAngle = struct.unpack_from("ffff", data, offset+4+100)
  # size 328, skip 3x3 matrix + 3x1 matrix = 12*4 = 48 bytes *4 NB_NAVDATA_DETECTION_RESULTS = 192
  cameraSource = struct.unpack_from("IIII", data, offset+4+116+192)
  return (countTypes, x, y, height, width, dist, oriAngle, cameraSource)

def parseRawMeasuresTag( data, offset ):
  "tag == NAVDATA_RAW_MEASURES_TAG"
  # 52 bytes = 2*18+3*4=36+12=48 (+4header)
  raw = struct.unpack_from("=HHHhhhhhIhhhhhhhhhIih", data, offset+4)
  return raw[:3]

def parseAltitudeTag( data, offset ):
  """  tag == NAVDATA_ALTITUDE_TAG
typedef struct _navdata_altitude_t {
  uint16_t   tag;
  uint16_t   size;

  int32_t   altitude_vision;
  float32_t altitude_vz;
  int32_t   altitude_ref;
  int32_t   altitude_raw;

  float32_t		obs_accZ;
  float32_t 	obs_alt;
  vector31_t 	obs_x;
  uint32_t 		obs_state;
  vector21_t	est_vb;
  uint32_t 		est_state ;

}_ATTRIBUTE_PACKED_ navdata_altitude_t;
"""
#      (altVision, altVz, altRef, altRaw) =
  return struct.unpack_from("ifiiff", data, offset+4)

def parseMagnetoTag( data, offset ):
  """ tag == NAVDATA_MAGNETO_TAG
typedef struct _navdata_magneto_t {
  uint16_t   tag;
  uint16_t   size;

  int16_t   	mx;
  int16_t   	my;
  int16_t   	mz;
  vector31_t 	magneto_raw;       // magneto in the body frame, in mG
  vector31_t 	magneto_rectified;
  vector31_t 	magneto_offset;
  float32_t 	heading_unwrapped;
  float32_t 	heading_gyro_unwrapped;
  float32_t 	heading_fusion_unwrapped;
  char 			magneto_calibration_ok;
  uint32_t      magneto_state;
  float32_t 	magneto_radius;
  float32_t     error_mean;
  float32_t     error_var;

}_ATTRIBUTE_PACKED_ navdata_magneto_t;
"""
  return struct.unpack_from("=hhhffffffffffffcIfff", data, offset+4)

def parseNavData( packet ):
  offset = 0
  header =  struct.unpack_from("IIII", packet, offset)
  print "ID", header[2], hex(header[1]), "ACK", header[1] >> 6 & 1, "WDOG", header[1] >> 30 & 1
  time,alt,ctrl = None,None,None
  offset += struct.calcsize("IIII")
  while True:
    tag, size =  struct.unpack_from("HH", packet, offset)
    offset += struct.calcsize("HH")
    values = []
    print tag, size
    for i in range(size-struct.calcsize("HH")):
      values.append(struct.unpack_from("c", packet, offset)[0])
      offset += struct.calcsize("c")
    if tag == NAVDATA_CKS_TAG:
      break
    if tag == NAVDATA_DEMO_TAG:
      values = parseDemoTag( "ABCD" + "".join(values), 0 )
      print values
      print "CTRL STATE", values['ctrl_state']
      alt = values['altitude']
      ctrl = values['ctrl_state']
#CTRL_DEFAULT=0, CTRL_INIT=1, CTRL_LANDED=2, CTRL_FLYING=3, CTRL_HOVERING=4, CTRL_TEST=5,
#CTRL_TRANS_TAKEOFF=6, CTRL_TRANS_GOTOFIX=7, CTRL_TRANS_LANDING=8, CTRL_TRANS_LOOPING=9

    if tag == NAVDATA_TIME_TAG:
      time = parseTimeTag("ABCD"+"".join(values), 0)
      print "TIME\t%f\t%s" % (time, hex(struct.unpack_from("I", "".join(values))[0]))

    if tag == NAVDATA_RAW_MEASURES_TAG:
      # 52 bytes = 2*18+3*4=36+12=48 (+4header)
      raw = struct.unpack_from("=HHHhhhhhIhhhhhhhhhIih", "".join(values))
      print "RAW", "\t".join( [str(x) for x in raw] )
      print parseRawMeasuresTag( "ABCD"+"".join(values), 0 )

    if tag == NAVDATA_ALTITUDE_TAG:
      (altVision, altVz, altRef, altRaw) = struct.unpack_from("ifii", "".join(values))
#      print "ALT", (altVision, altVz, altRef, altRaw)

    if tag == NAVDATA_MAGNETO_TAG:
      magneto = parseMagnetoTag("ABCD"+ "".join(values), 0 )
      values = dict(zip(['mx', 'my', 'mz',
        'magneto_raw_x', 'magneto_raw_y', 'magneto_raw_z',
        'magneto_rectified_x', 'magneto_rectified_y', 'magneto_rectified_z',
        'magneto_offset_x', 'magneto_offset_y', 'magneto_offset_z',
        'heading_unwrapped', 'heading_gyro_unwrapped', 'heading_fusion_unwrapped',
        'magneto_calibration_ok', 'magneto_state', 'magneto_radius',
        'error_mean', 'error_var'], magneto))
#      print "compass:\t%d\t%d\t%d\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f" % tuple([values[x] for x in ['mx', 'my', 'mz',
#        'magneto_raw_x', 'magneto_raw_y', 'magneto_raw_z',
#        'magneto_rectified_x', 'magneto_rectified_y', 'magneto_rectified_z',
#        'magneto_offset_x', 'magneto_offset_y', 'magneto_offset_z',
#        ]])
      print "compass:\t"+"\t".join( [str(x) for x in magneto] )

    if tag == NAVDATA_VISION_DETECT_TAG:
      (countTypes, x, y, height, width, dist, oriAngle, cameraSource) = parseVisionDetectTag( "ABCD" + "".join(values), 0 )
      print "TAG", countTypes
      print "TAG", x[0],y[0], height[0], width[0], dist[0]/100.0, oriAngle[0], cameraSource[1]
  if time and ctrl != 2:
    print "ALT\t%f\t%d\t%d" % (time, ctrl, alt)
  return offset

if __name__ == "__main__":
  if len(sys.argv) < 2:
    print __doc__
    sys.exit(2)

  filename = sys.argv[1]
  if filename.endswith(".gz"):
    packet = gzip.open(filename, "rb").read()
  else:
    packet = open(filename, "rb").read()

  offset = 0
  while offset < len(packet):
  #for i in xrange(3):
    offset += parseNavData( packet[offset:] )

<commit_msg>added parsing NAVDATA_TRACKERS_SEND_TAG (but getting zeros only)<commit_after>import struct
import sys
import gzip

"""
#define NAVDATA_PORT              5554
#define NAVDATA_HEADER            0x55667788
#define NAVDATA_BUFFER_SIZE       2048

    NAVDATA_DEMO_TAG = 0,
    NAVDATA_VISION_DETECT_TAG = 16,
    NAVDATA_IPHONE_ANGLES_TAG = 18,
    NAVDATA_CKS_TAG = 0xFFFF

NAVDATA_OPTION( navdata_time_t,           navdata_time            , NAVDATA_TIME_TAG             ) 1
NAVDATA_OPTION( navdata_raw_measures_t,   navdata_raw_measures    , NAVDATA_RAW_MEASURES_TAG     ) 2
NAVDATA_OPTION( navdata_phys_measures_t,  navdata_phys_measures   , NAVDATA_PHYS_MEASURES_TAG    ) 3
NAVDATA_OPTION( navdata_gyros_offsets_t,  navdata_gyros_offsets   , NAVDATA_GYROS_OFFSETS_TAG    ) 4
NAVDATA_OPTION( navdata_euler_angles_t,   navdata_euler_angles    , NAVDATA_EULER_ANGLES_TAG     ) 5
NAVDATA_OPTION( navdata_references_t,     navdata_references      , NAVDATA_REFERENCES_TAG       ) 6
NAVDATA_OPTION( navdata_trims_t,          navdata_trims           , NAVDATA_TRIMS_TAG            ) 7
NAVDATA_OPTION( navdata_rc_references_t,  navdata_rc_references   , NAVDATA_RC_REFERENCES_TAG    ) 8
NAVDATA_OPTION( navdata_pwm_t,            navdata_pwm             , NAVDATA_PWM_TAG              ) 9
NAVDATA_OPTION( navdata_altitude_t,       navdata_altitude        , NAVDATA_ALTITUDE_TAG         ) 10
NAVDATA_OPTION( navdata_vision_raw_t,     navdata_vision_raw      , NAVDATA_VISION_RAW_TAG       ) 11
NAVDATA_OPTION( navdata_vision_of_t,      navdata_vision_of       , NAVDATA_VISION_OF_TAG        ) 12
NAVDATA_OPTION( navdata_vision_t,         navdata_vision          , NAVDATA_VISION_TAG           ) 13
NAVDATA_OPTION( navdata_vision_perf_t ,   navdata_vision_perf     , NAVDATA_VISION_PERF_TAG      ) 14
NAVDATA_OPTION( navdata_trackers_send_t,  navdata_trackers_send   , NAVDATA_TRACKERS_SEND_TAG    ) 15
NAVDATA_OPTION( navdata_vision_detect_t,  navdata_vision_detect   , NAVDATA_VISION_DETECT_TAG    ) 16
NAVDATA_OPTION( navdata_watchdog_t  ,     navdata_watchdog        , NAVDATA_WATCHDOG_TAG         ) 17
NAVDATA_OPTION( navdata_adc_data_frame_t, navdata_adc_data_frame  , NAVDATA_ADC_DATA_FRAME_TAG   ) 18
NAVDATA_OPTION( navdata_video_stream_t,   navdata_video_stream    , NAVDATA_VIDEO_STREAM_TAG     ) 19
NAVDATA_OPTION( navdata_games_t,          navdata_games           , NAVDATA_GAMES_TAG            ) 20
NAVDATA_OPTION( navdata_pressure_raw_t,   navdata_pressure_raw    , NAVDATA_PRESSURE_RAW_TAG		 ) 21
NAVDATA_OPTION( navdata_magneto_t,       	navdata_magneto					, NAVDATA_MAGNETO_TAG					 ) 22
NAVDATA_OPTION( navdata_wind_speed_t,     navdata_wind_speed      , NAVDATA_WIND_TAG						 ) 23
NAVDATA_OPTION( navdata_kalman_pressure_t,navdata_kalman_pressure	, NAVDATA_KALMAN_PRESSURE_TAG	 ) 24
NAVDATA_OPTION( navdata_hdvideo_stream_t ,navdata_hdvideo_stream  , NAVDATA_HDVIDEO_STREAM_TAG	 ) 25
NAVDATA_OPTION( navdata_wifi_t           ,navdata_wifi            , NAVDATA_WIFI_TAG             ) 26

typedef struct _navdata_magneto_t {
  uint16_t   tag;
  uint16_t   size;

  int16_t   	mx;
  int16_t   	my;
  int16_t   	mz;
  vector31_t 	magneto_raw;       // magneto in the body frame, in mG
  vector31_t 	magneto_rectified;
  vector31_t 	magneto_offset;
  float32_t 	heading_unwrapped;
  float32_t 	heading_gyro_unwrapped;
  float32_t 	heading_fusion_unwrapped;
  char 			magneto_calibration_ok;
  uint32_t      magneto_state;
  float32_t 	magneto_radius;
  float32_t     error_mean;
  float32_t     error_var;

}_ATTRIBUTE_PACKED_ navdata_magneto_t;

"""
NAVDATA_DEMO_TAG = 0
NAVDATA_TIME_TAG = 1
NAVDATA_RAW_MEASURES_TAG = 2
NAVDATA_ALTITUDE_TAG = 10
NAVDATA_TRACKERS_SEND_TAG = 15
NAVDATA_VISION_DETECT_TAG = 16
NAVDATA_IPHONE_ANGLES_TAG = 18
NAVDATA_MAGNETO_TAG = 22
NAVDATA_CKS_TAG = 0xFFFF

#    drone_state['navdata_bootstrap']    = _[1] >> 11 & 1 # Navdata bootstrap : (0) options sent in all or demo mode, (1) no navdata options sent */
#     drone_state['com_watchdog_mask']    = _[1] >> 30 & 1 # Communication Watchdog : (1) com problem, (0) Com is ok */

#    drone_state['command_mask']         = _[1] >>  6 & 1 # Control command ACK : (0) None, (1) one received */

def parseTimeTag( data, offset ):
  "uint32_t - the 11 most significant bits represents the seconds, and the 21 least significant bits are the microseconds."
# tag == NAVDATA_TIME_TAG:
  utime = struct.unpack_from("I", data, offset+4)[0]
  assert utime & (1<<20) == 0, str( (hex(utime), header[2]) )
  return (utime >> 21) + (utime & 0xFFFFF)/1000000.0

def parseDemoTag( data, offset ):
  values = struct.unpack_from("IIfffifff", data, offset+4)
  values = dict(zip(['ctrl_state', 'battery', 'theta', 'phi', 'psi', 'altitude', 'vx', 'vy', 'vz'], values))
  values['ctrl_state'] >>= 16
  return values

def parseTrackersSendTag( data, offset ):
  values = struct.unpack_from("iii"*30, data, offset+4) # locked, (x,y)
  return values

def parseVisionDetectTag( data, offset ):
  "tag == NAVDATA_VISION_DETECT_TAG"
  countTypes = struct.unpack_from("IIIII", data, offset+4)
  x = struct.unpack_from("IIII", data, offset+4+20)
  y = struct.unpack_from("IIII", data, offset+4+36)
  height = struct.unpack_from("IIII", data, offset+4+52)
  width = struct.unpack_from("IIII", data, offset+4+68)
  dist = struct.unpack_from("IIII", data, offset+4+84)
  oriAngle = struct.unpack_from("ffff", data, offset+4+100)
  # size 328, skip 3x3 matrix + 3x1 matrix = 12*4 = 48 bytes *4 NB_NAVDATA_DETECTION_RESULTS = 192
  cameraSource = struct.unpack_from("IIII", data, offset+4+116+192)
  return (countTypes, x, y, height, width, dist, oriAngle, cameraSource)

def parseRawMeasuresTag( data, offset ):
  "tag == NAVDATA_RAW_MEASURES_TAG"
  # 52 bytes = 2*18+3*4=36+12=48 (+4header)
  raw = struct.unpack_from("=HHHhhhhhIhhhhhhhhhIih", data, offset+4)
  return raw[:3]

def parseAltitudeTag( data, offset ):
  """  tag == NAVDATA_ALTITUDE_TAG
typedef struct _navdata_altitude_t {
  uint16_t   tag;
  uint16_t   size;

  int32_t   altitude_vision;
  float32_t altitude_vz;
  int32_t   altitude_ref;
  int32_t   altitude_raw;

  float32_t		obs_accZ;
  float32_t 	obs_alt;
  vector31_t 	obs_x;
  uint32_t 		obs_state;
  vector21_t	est_vb;
  uint32_t 		est_state ;

}_ATTRIBUTE_PACKED_ navdata_altitude_t;
"""
#      (altVision, altVz, altRef, altRaw) =
  return struct.unpack_from("ifiiff", data, offset+4)

def parseMagnetoTag( data, offset ):
  """ tag == NAVDATA_MAGNETO_TAG
typedef struct _navdata_magneto_t {
  uint16_t   tag;
  uint16_t   size;

  int16_t   	mx;
  int16_t   	my;
  int16_t   	mz;
  vector31_t 	magneto_raw;       // magneto in the body frame, in mG
  vector31_t 	magneto_rectified;
  vector31_t 	magneto_offset;
  float32_t 	heading_unwrapped;
  float32_t 	heading_gyro_unwrapped;
  float32_t 	heading_fusion_unwrapped;
  char 			magneto_calibration_ok;
  uint32_t      magneto_state;
  float32_t 	magneto_radius;
  float32_t     error_mean;
  float32_t     error_var;

}_ATTRIBUTE_PACKED_ navdata_magneto_t;
"""
  return struct.unpack_from("=hhhffffffffffffcIfff", data, offset+4)

def parseNavData( packet ):
  offset = 0
  header =  struct.unpack_from("IIII", packet, offset)
  print "ID", header[2], hex(header[1]), "ACK", header[1] >> 6 & 1, "WDOG", header[1] >> 30 & 1
  time,alt,ctrl = None,None,None
  offset += struct.calcsize("IIII")
  while True:
    tag, size =  struct.unpack_from("HH", packet, offset)
    offset += struct.calcsize("HH")
    values = []
    print tag, size
    for i in range(size-struct.calcsize("HH")):
      values.append(struct.unpack_from("c", packet, offset)[0])
      offset += struct.calcsize("c")
    if tag == NAVDATA_CKS_TAG:
      break
    if tag == NAVDATA_DEMO_TAG:
      values = parseDemoTag( "ABCD" + "".join(values), 0 )
      print values
      print "CTRL STATE", values['ctrl_state']
      alt = values['altitude']
      ctrl = values['ctrl_state']
#CTRL_DEFAULT=0, CTRL_INIT=1, CTRL_LANDED=2, CTRL_FLYING=3, CTRL_HOVERING=4, CTRL_TEST=5,
#CTRL_TRANS_TAKEOFF=6, CTRL_TRANS_GOTOFIX=7, CTRL_TRANS_LANDING=8, CTRL_TRANS_LOOPING=9

    if tag == NAVDATA_TIME_TAG:
      time = parseTimeTag("ABCD"+"".join(values), 0)
      print "TIME\t%f\t%s" % (time, hex(struct.unpack_from("I", "".join(values))[0]))

    if tag == NAVDATA_RAW_MEASURES_TAG:
      # 52 bytes = 2*18+3*4=36+12=48 (+4header)
      raw = struct.unpack_from("=HHHhhhhhIhhhhhhhhhIih", "".join(values))
      print "RAW", "\t".join( [str(x) for x in raw] )
      print parseRawMeasuresTag( "ABCD"+"".join(values), 0 )

    if tag == NAVDATA_ALTITUDE_TAG:
      (altVision, altVz, altRef, altRaw) = struct.unpack_from("ifii", "".join(values))
#      print "ALT", (altVision, altVz, altRef, altRaw)

    if tag == NAVDATA_TRACKERS_SEND_TAG:
      print "TRACKERS", parseTrackersSendTag( "ABCD"+"".join(values), 0 )

    if tag == NAVDATA_MAGNETO_TAG:
      magneto = parseMagnetoTag("ABCD"+ "".join(values), 0 )
      values = dict(zip(['mx', 'my', 'mz',
        'magneto_raw_x', 'magneto_raw_y', 'magneto_raw_z',
        'magneto_rectified_x', 'magneto_rectified_y', 'magneto_rectified_z',
        'magneto_offset_x', 'magneto_offset_y', 'magneto_offset_z',
        'heading_unwrapped', 'heading_gyro_unwrapped', 'heading_fusion_unwrapped',
        'magneto_calibration_ok', 'magneto_state', 'magneto_radius',
        'error_mean', 'error_var'], magneto))
#      print "compass:\t%d\t%d\t%d\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f" % tuple([values[x] for x in ['mx', 'my', 'mz',
#        'magneto_raw_x', 'magneto_raw_y', 'magneto_raw_z',
#        'magneto_rectified_x', 'magneto_rectified_y', 'magneto_rectified_z',
#        'magneto_offset_x', 'magneto_offset_y', 'magneto_offset_z',
#        ]])
      print "compass:\t"+"\t".join( [str(x) for x in magneto] )

    if tag == NAVDATA_VISION_DETECT_TAG:
      (countTypes, x, y, height, width, dist, oriAngle, cameraSource) = parseVisionDetectTag( "ABCD" + "".join(values), 0 )
      print "TAG", countTypes
      print "TAG", x[0],y[0], height[0], width[0], dist[0]/100.0, oriAngle[0], cameraSource[1]
  if time and ctrl != 2:
    print "ALT\t%f\t%d\t%d" % (time, ctrl, alt)
  return offset

if __name__ == "__main__":
  if len(sys.argv) < 2:
    print __doc__
    sys.exit(2)

  filename = sys.argv[1]
  if filename.endswith(".gz"):
    packet = gzip.open(filename, "rb").read()
  else:
    packet = open(filename, "rb").read()

  offset = 0
  while offset < len(packet):
  #for i in xrange(3):
    offset += parseNavData( packet[offset:] )

<|endoftext|>


<commit_before>from series import Series
from itertools import combinations
from blessings import Terminal
from tabulate import tabulate

class Tournament(object):
    def __init__(self,
                 players,
                 numberOfGames,
                 alternateFirstPlayer=True,
                 debug=False,
                 boardWidth=None,
                 boardHeight=None,
                 showVisualization=False,
                 visualizationInterval=.01,
                 showStatistics=False,
                 clearBoardOnException=False):
        self.players = players
        self.numberOfGames = numberOfGames
        self.alternateFirstPlayer = alternateFirstPlayer
        self.debug = debug
        self.boardWidth = boardWidth
        self.boardHeight = boardHeight
        self.showVisualization = showVisualization
        self.visualizationInterval = visualizationInterval
        self.showStatistics = showStatistics
        self.clearBoardOnException = clearBoardOnException
        self.term = Terminal()

    def run(self):
        self.results = dict([(player, [{'win': 0,
                                        'lose': 0,
                                        'draw': 0}, []]) for player in self.players])
        self.series = [Series(x[0](),
                              x[1](),
                              self.numberOfGames,
                              alternateFirstPlayer=self.alternateFirstPlayer,
                              debug=self.debug,
                              boardWidth=self.boardWidth,
                              boardHeight=self.boardHeight,
                              showVisualization=self.showVisualization,
                              visualizationInterval=self.visualizationInterval,
                              clearBoardOnException=self.clearBoardOnException,
                              tournament=self)
                            for x in combinations(self.players, 2)]

        self.series[0].player1._initializeGameBoard()
        self.series[0].player2._initializeGameBoard()
        self.displayLeaderBoard(nextGameIndex=1)

        for idx, series in enumerate(self.series):
            if self.showVisualization:
                print self.term.clear
                self.series[0].player1._initializeGameBoard()
                self.series[0].player2._initializeGameBoard()
                series.printStats()
            self.displayLeaderBoard(nextGameIndex=idx + 1)

            result = series.start()
            if result is not None:
                self.results[type(result[0])][0]['win'] += 1
                self.results[type(result[1])][0]['lose'] += 1

                self.results[type(result[0])][1].append(type(result[1]).__name__)
            else:
                # A null result means we got a draw
                self.results[type(result[0])][0]['draw'] += 1
                self.results[type(result[1])][0]['draw'] += 1

            print
            self.displayLeaderBoard(nextGameIndex=idx + 1)

        print self.term.move(0, 0)
        print self.term.clear
        self.displayLeaderBoard()
        print
        print
        self.finalResults()
        print

    def displayLeaderBoard(self, nextGameIndex=None):
        rankings = sorted(self.results.items(), key=lambda x: (-x[1][0]['win'], sum(x[1][0].values())))
        data = []
        for idx, ranking in enumerate(rankings):
            data.append(('%s: %s' % (idx + 1, ranking[0].__name__),
                         ranking[1][0]['win'],
                         ranking[1][0]['lose'],
                         ranking[1][0]['draw'],
                         sum(ranking[1][0].values())))
        table = tabulate(data, headers=['Player', 'Wins', 'Losses', 'Draws', 'GP'])

        if nextGameIndex is not None and nextGameIndex < len(self.series):
            print self.term.bold('Next matchup:') + ' %s v. %s' % (self.series[nextGameIndex].player1.name,
                                                                   self.series[nextGameIndex].player2.name)
            print
        print self.term.bold('LeaderBoard')
        print table

    def finalResults(self):
        rankings = sorted(self.results.items(), key=lambda x: -x[1][0]['win'])
        for idx, ranking in enumerate(rankings):
            print '%s: %s' % (idx + 1, ranking[0].__name__)
            print '   with wins against %s' % ranking[1][1]
<commit_msg>Shuffling opponents<commit_after>from series import Series
from itertools import combinations
from blessings import Terminal
from tabulate import tabulate
import random

class Tournament(object):
    def __init__(self,
                 players,
                 numberOfGames,
                 alternateFirstPlayer=True,
                 debug=False,
                 boardWidth=None,
                 boardHeight=None,
                 showVisualization=False,
                 visualizationInterval=.01,
                 showStatistics=False,
                 clearBoardOnException=False):
        self.players = players
        self.numberOfGames = numberOfGames
        self.alternateFirstPlayer = alternateFirstPlayer
        self.debug = debug
        self.boardWidth = boardWidth
        self.boardHeight = boardHeight
        self.showVisualization = showVisualization
        self.visualizationInterval = visualizationInterval
        self.showStatistics = showStatistics
        self.clearBoardOnException = clearBoardOnException
        self.term = Terminal()

    def run(self):
        self.results = dict([(player, [{'win': 0,
                                        'lose': 0,
                                        'draw': 0}, []]) for player in self.players])
        self.series = [Series(x[0](),
                              x[1](),
                              self.numberOfGames,
                              alternateFirstPlayer=self.alternateFirstPlayer,
                              debug=self.debug,
                              boardWidth=self.boardWidth,
                              boardHeight=self.boardHeight,
                              showVisualization=self.showVisualization,
                              visualizationInterval=self.visualizationInterval,
                              clearBoardOnException=self.clearBoardOnException,
                              tournament=self)
                            for x in combinations(self.players, 2)]
        random.shuffle(self.series)

        self.series[0].player1._initializeGameBoard()
        self.series[0].player2._initializeGameBoard()
        self.displayLeaderBoard(nextGameIndex=1)

        for idx, series in enumerate(self.series):
            if self.showVisualization:
                print self.term.clear
                self.series[0].player1._initializeGameBoard()
                self.series[0].player2._initializeGameBoard()
                series.printStats()
            self.displayLeaderBoard(nextGameIndex=idx + 1)

            result = series.start()
            if result is not None:
                self.results[type(result[0])][0]['win'] += 1
                self.results[type(result[1])][0]['lose'] += 1

                self.results[type(result[0])][1].append(type(result[1]).__name__)
            else:
                # A null result means we got a draw
                self.results[type(result[0])][0]['draw'] += 1
                self.results[type(result[1])][0]['draw'] += 1

            print
            self.displayLeaderBoard(nextGameIndex=idx + 1)

        print self.term.move(0, 0)
        print self.term.clear
        self.displayLeaderBoard()
        print
        print
        self.finalResults()
        print

    def displayLeaderBoard(self, nextGameIndex=None):
        rankings = sorted(self.results.items(), key=lambda x: (-x[1][0]['win'], sum(x[1][0].values())))
        data = []
        for idx, ranking in enumerate(rankings):
            data.append(('%s: %s' % (idx + 1, ranking[0].__name__),
                         ranking[1][0]['win'],
                         ranking[1][0]['lose'],
                         ranking[1][0]['draw'],
                         sum(ranking[1][0].values())))
        table = tabulate(data, headers=['Player', 'Wins', 'Losses', 'Draws', 'GP'])

        if nextGameIndex is not None and nextGameIndex < len(self.series):
            print self.term.bold('Next matchup:') + ' %s v. %s' % (self.series[nextGameIndex].player1.name,
                                                                   self.series[nextGameIndex].player2.name)
            print
        print self.term.bold('LeaderBoard')
        print table

    def finalResults(self):
        rankings = sorted(self.results.items(), key=lambda x: -x[1][0]['win'])
        for idx, ranking in enumerate(rankings):
            print '%s: %s' % (idx + 1, ranking[0].__name__)
            print '   with wins against %s' % ranking[1][1]
<|endoftext|>


<commit_before>from six import string_types

from django.db.models import signals

from .invalidation import invalidate_paths

def register(model):
    register_instance_function_at_save(model, invalidate_model_paths)

def register_instance_function_at_save(model, function):

    def save_function(sender, instance, **kwargs):
        function(instance)

    signals.post_save.connect(save_function, model, weak=False)
    signals.pre_delete.connect(save_function, model, weak=False)

def get_paths_from_model(model):
    paths = model.dependent_paths()
    if isinstance(paths, string_types):
        model_name = model.__class__.__name__
        raise TypeError(
            ('dependent_paths on {} should return a list of paths, not a'
             'string'.format(model_name))
        )
    return paths

def invalidate_model_paths(model):
    paths = get_paths_from_model(model)
    invalidate_paths(paths)
<commit_msg>Use keyword based `format` to maintain 2.6 compatibility<commit_after>from six import string_types

from django.db.models import signals

from .invalidation import invalidate_paths

def register(model):
    register_instance_function_at_save(model, invalidate_model_paths)

def register_instance_function_at_save(model, function):

    def save_function(sender, instance, **kwargs):
        function(instance)

    signals.post_save.connect(save_function, model, weak=False)
    signals.pre_delete.connect(save_function, model, weak=False)

def get_paths_from_model(model):
    paths = model.dependent_paths()
    if isinstance(paths, string_types):
        model_name = model.__class__.__name__
        raise TypeError(
            ('dependent_paths on {model_name} should return a list of paths, '
             ' not a string'.format(model_name=model_name))
        )
    return paths

def invalidate_model_paths(model):
    paths = get_paths_from_model(model)
    invalidate_paths(paths)
<|endoftext|>


<commit_before>from .base import BaseChart
import json
from collections import defaultdict
from decimal import Decimal

from django.template.loader import render_to_string
from ..utils import JSONEncoderForHTML

class BaseHighCharts(BaseChart):
    def get_html_template(self):
        return "graphos/highcharts/html.html"

    def get_js_template(self):
        return "graphos/highcharts/js.html"

    def get_series(self):
        """
        Example usage:
            data = [
               ['Year', 'Sales', 'Expenses', 'Items Sold', 'Net Profit'],
               ['2004', 1000, 400, 100, 600],
               ['2005', 1170, 460, 120, 310],
               ['2006', 660, 1120, 50, -460],
               ['2007', 1030, 540, 100, 200],
            ]
            sd = SimpleDataSource(data)
            hc = BaseHighCharts(sd)
            hc.get_series() would be [{"name": "Sales", "data": [1000, 1170, 660, 1030]}, {"name": "Expenses", "data": [400, 460, 1120, 540]} ....]
        """
        data = self.get_data()
        series_names = data[0][1:]
        serieses = []
        options = self.get_options()
        for i, name in enumerate(series_names):
            series = {"name": name, "data": column(data, i+1)[1:]}
            # If colors was passed then add color for the serieses
            if 'colors' in options and len(options['colors']) > i:
                series['color'] = options['colors'][i]
            serieses.append(series)
        serieses = self.add_series_options(serieses)
        return serieses

    def add_series_options(self, serieses):
        # hookpoint. You can subclass BaseHighCharts or its subclasses
        # and override this method to modify serieses.
        # eg: If you want to add dashStyle for a particular series of serieses
        # See http://api.highcharts.com/highcharts/ for options that can be added for series
        return serieses

    def get_series_json(self):
        serieses = self.get_series()
        return json.dumps(serieses, cls=JSONEncoderForHTML)

    def get_categories(self):
        """
        This would return [2004, 2005, 2006, 2007]
        """
        return column(self.get_data(), 0)[1:]

    def get_categories_json(self):
        categories = self.get_categories()
        return json.dumps(categories, cls=JSONEncoderForHTML)

    def get_title(self):
        title = self.get_options().get('title', {})
        if type(title) == str:
            title = {'text': title}
        return title

    def get_title_json(self):
        title = self.get_title()
        return json.dumps(title, cls=JSONEncoderForHTML)

    def get_subtitle(self):
        subtitle = self.get_options().get('subtitle', {})
        if type(subtitle) == str:
            subtitle = {'text': subtitle}
        return subtitle

    def get_subtitle_json(self):
        subtitle = self.get_subtitle()
        return json.dumps(subtitle, cls=JSONEncoderForHTML)

    def get_chart(self):
        chart = self.get_options().get('chart', {})
        chart['type'] = self.get_chart_type()
        return chart

    def get_chart_json(self):
        chart = self.get_chart()
        return json.dumps(chart, cls=JSONEncoderForHTML)

    def get_x_axis(self):
        x_axis = self.get_options().get('xAxis', {})
        if not 'categories' in x_axis:
            x_axis['categories'] = self.get_categories()
        if not 'title' in x_axis:
            x_axis['title'] = {}
        if not 'text' in x_axis['title']:
            x_axis['title']['text'] = self.get_x_axis_title()
        return x_axis

    def get_x_axis_json(self):
        x_axis = self.get_x_axis()
        return json.dumps(x_axis, cls=JSONEncoderForHTML)

    def get_y_axis(self):
        y_axis = self.get_options().get('yAxis', {})
        return y_axis

    def get_y_axis_json(self):
        y_axis = self.get_y_axis()
        return json.dumps(y_axis, cls=JSONEncoderForHTML)

    def get_tooltip(self):
        tooltip = self.get_options().get('tooltip', {})
        return tooltip

    def get_tooltip_json(self):
        tooltip = self.get_tooltip()
        return json.dumps(tooltip, cls=JSONEncoderForHTML)

    def get_x_axis_title(self):
        return self.get_data()[0][0]

class LineChart(BaseHighCharts):
    def get_chart_type(self):
        return "line"

class BarChart(BaseHighCharts):
    def get_chart_type(self):
        return "bar"

class ColumnChart(BaseHighCharts):
    def get_chart_type(self):
        return "column"

class ColumnLineChart(BaseHighCharts):
    """
    First series will be plotted as column
    Every subsequent series will be plotted as line
    """

    def get_series(self):
        data = self.get_data()
        serieses = []
        # TODO: Add color ability
        serieses.append({"name": data[0][1], "data": column(data, 1)[1:], "type": "column"})
        series_names = data[0][2:]
        for i, name in enumerate(series_names):
            serieses.append({"name": name, "data": column(data, i+2)[1:], "type": "line"})
        return serieses

    def get_chart_type(self):
        # TODO: This is a placeholder so that get_chart() doesn't fail. Think how we can fix this.
        return "column_line"

class LineColumnChart(BaseHighCharts):
    """
    First series will be plotted as line
    Every subsequent series will be plotted as column
    """

    def get_series(self):
        data = self.get_data()
        serieses = []
        # TODO: Add color ability
        serieses.append({"name": data[0][1], "data": column(data, 1)[1:], "type": "line"})
        series_names = data[0][2:]
        for i, name in enumerate(series_names):
            serieses.append({"name": name, "data": column(data, i+2)[1:], "type": "column"})
        return serieses

    def get_chart_type(self):
        return "line_column"

class PieChart(BaseHighCharts):
    def get_series(self):
        data = self.get_data()
        series_names = data[0][1:]
        serieses = []
        for i, name in enumerate(series_names):
            # TODO: Add color ability
            series = {"name": name, "data": pie_column(data, i+1)[1:]}
            serieses.append(series)
        return serieses

    def get_chart_type(self):
        return "pie"

class AreaChart(BaseHighCharts):
    def get_chart_type(self):
        return "area"

class DonutChart(PieChart):
    def get_js_template(self):
        return "graphos/highcharts/js_donut.html"

    def get_chart(self):
        chart = super(DonutChart, self).get_chart()
        chart['options3d'] = {'enabled': True, 'alpha': 45}
        return chart

    def get_plot_options(self):
        plot_options = self.get_options().get('plotOptions', {})
        plot_options['pie'] = {'innerSize': 100, 'depth': 45}
        return plot_options

    def get_plot_options_json(self):
        plot_options = self.get_plot_options()
        return json.dumps(plot_options, cls=JSONEncoderForHTML)

class ScatterChart(BaseHighCharts):
    def get_chart_type(self):
        return "scatter"

class LogarithmicChart(BaseHighCharts):
    def get_series(self):
        data = super(LogarithmicChart, self).get_series()
        data = data[0].get('data')
        return data

    def get_js_template(self):
        return "graphos/highcharts/js_log.html"

    def get_chart_type(self):
        return "log_chart"

class MultiAxisChart(BaseHighCharts):
    # TODO: This should be renamed dual axis, its not multi axis
    # It will break with more than two serieses
    def get_series(self):
        serieses = super(MultiAxisChart, self).get_series()
        chart_types = ['column', 'spline']
        # Make series 0 as column and series 1 as line
        for i, series in enumerate(serieses):
            if i == 0:
                series['yAxis'] = 1
            series['type'] = chart_types[i]
        return serieses

    def get_y_axis(self):
        y_axis = super(MultiAxisChart, self).get_y_axis()
        # This is overriding any thing set in yAxis. Fix
        y_axis = []
        y_axis.append({'title': {'text': self.get_series()[1]['name']}})
        y_axis.append({'title': {'text': self.get_series()[0]['name']}, 'opposite': True})
        return y_axis

    def get_chart_type(self):
        return "multi_axis"

class HighMap(BaseHighCharts):
    """docstring for HighMaps"""
    def __init__(self, *args, **kwargs):
        super(HighMap, self).__init__(*args, **kwargs)
        if type(self.get_data()[1][1]) in [int, float, long, Decimal]: # TODO: It could be any numeric, not just int
            self.series_type = 'single_series'
        else:
            self.series_type = 'multi_series'

    def get_series(self):
        # Currently graphos highmap only work with two columns, essentially that means only one series
        # That's why you see kv[1] and nothing beyond kv[1]
        # Can highcharts maps make sense for multiple serieses?
        """
        Different serieses should come up based on different data formats passed.
            1. Single series
                This would be a choropleth map where the color intensity of different regions/polygons
                differ based on the integer values in series. Two things are important here
                    a: It works with a colorAxis
                    b: First series i.e second column of tabular data must be integer.
            2. Multiple series
                Example
                State     Winner    Seats
                Orissa    BJP       5
                Bihar     RJD       10
                Assam     BJP       7
                Meghalaya AAP       12
                Manipur   AAP       4
                Punjab    AAP       4

                In this case all states won by AAP make up one series and will be colored in a particular color.
                Then all states won by BJP will be colored in a particular color. This color will be different from AAP color.
                But colorAxis doesn't make sense here. It's not a choropleth map.
                Graphos internally finds out all the distinct entries of second column of tabular data and created different serieses for different states.
        """
        if self.series_type == 'single_series':
            serieses = self.calculate_single_series()
        else:
            serieses = self.calculate_multi_series()
        return serieses

    def calculate_multi_series(self):
        data = self.get_data()[1:]
        name_to_regions_dict = defaultdict(list)
        second_column_onwards_names = self.get_data()[0][2:]
        chart_type = self.get_chart_type()
        for row in data:
            series_name = row[1]
            # Create a dictionary of format {'code': 'Orissa', 'Seats': 5}
            d = {'code': row[0]}
            second_column_onwards = row[2:]
            second_column_onwards_dict = dict(zip(second_column_onwards_names, second_column_onwards))
            # If it is a mapbubble, add 'z' based on some key
            if chart_type == 'mapbubble':
                zKey = self.get_options().get('zKey')
                if zKey:
                    d['z'] = second_column_onwards_dict[zKey]
            d.update(second_column_onwards_dict)
            name_to_regions_dict[series_name].append(d)
        serieses = []
        join_by = self.get_options().get('joinBy', 'hc-key')
        i = 0
        colors = self.get_options().get('colors', None)
        for series_name, regions in name_to_regions_dict.items():
            series = {}
            series['name'] = series_name
            series['data'] = regions
            series['joinBy'] = [join_by, 'code']
            #series['type'] = chart_type
            serieses.append(series)
            if colors and len(colors) > i:
                series['color'] = colors[i]
            i += 1
        if chart_type == 'mapbubble':
            just_for_sake_series = {}
            just_for_sake_series['name'] = 'Regions'
            just_for_sake_series['type'] = 'map'
            serieses.insert(0, just_for_sake_series)
        return serieses

    def calculate_single_series(self):
        data = self.get_data()[1:]
        first_series = {}
        options = self.get_options()
        first_series['data'] = []
        chart_type = self.get_chart_type()
        for i, kv in enumerate(data):
            if chart_type == 'mapbubble':
                region_detail = {'code': kv[0], 'z': kv[1]}
            elif chart_type == 'map':
                region_detail = {'code': kv[0], 'value': kv[1]}
            first_series['data'].append(region_detail)
        join_by = self.get_options().get('joinBy', 'hc-key')
        first_series['joinBy'] = [join_by, 'code']
        first_series['name'] = self.get_series_name()
        first_series['type'] = self.get_chart_type()
        serieses = []
        serieses.append(first_series)
        just_for_sake_series = {}
        just_for_sake_series['name'] = 'Regions'
        just_for_sake_series['type'] = 'map'
        serieses.insert(0, just_for_sake_series)
        return serieses

    def get_js_template(self):
        if self.series_type == 'single_series':
            return "graphos/highcharts/js_highmaps.html"
        else:
            return "graphos/highcharts/js_highmaps_multi_series.html"

    def get_map(self):
        # return "custom/world"
        # return "countries/us/custom/us-all-territories"
        return self.get_options().get('map_area', 'custom/world')

    def get_series_name(self):
        return self.get_data()[0][1]

    def get_color_axis(self):
        color_axis = self.get_options().get('colorAxis', {})
        return color_axis

    def get_color_axis_json(self):
        color_axis = self.get_color_axis()
        return json.dumps(color_axis, cls=JSONEncoderForHTML)

    def get_plot_options(self):
        plot_options = self.get_options().get('plotOptions', {})
        if not 'map' in plot_options:
            plot_options['map'] = {}
        if not 'mapbubble' in plot_options:
            plot_options['mapbubble'] = {}
        return plot_options

    def get_plot_options_json(self):
        plot_options = self.get_plot_options()
        return json.dumps(plot_options, cls=JSONEncoderForHTML)

    def get_chart_type(self):
        # If you are using mapbubble, ensure you don't set allAreas to False.
        # Also if you are setting mapbubble for a multi series chart, then probably you should set zKey too to get different bubble sizes.
        return self.get_options().get("map_type", "map")

def column(matrix, i):
    return [row[i] for row in matrix]

def pie_column(matrix, i):
    return [{'name':row[0],'y':row[i]} for row in matrix]
<commit_msg>Add placeholder map only if its a bubble chart<commit_after>from .base import BaseChart
import json
from collections import defaultdict
from decimal import Decimal

from django.template.loader import render_to_string
from ..utils import JSONEncoderForHTML

class BaseHighCharts(BaseChart):
    def get_html_template(self):
        return "graphos/highcharts/html.html"

    def get_js_template(self):
        return "graphos/highcharts/js.html"

    def get_series(self):
        """
        Example usage:
            data = [
               ['Year', 'Sales', 'Expenses', 'Items Sold', 'Net Profit'],
               ['2004', 1000, 400, 100, 600],
               ['2005', 1170, 460, 120, 310],
               ['2006', 660, 1120, 50, -460],
               ['2007', 1030, 540, 100, 200],
            ]
            sd = SimpleDataSource(data)
            hc = BaseHighCharts(sd)
            hc.get_series() would be [{"name": "Sales", "data": [1000, 1170, 660, 1030]}, {"name": "Expenses", "data": [400, 460, 1120, 540]} ....]
        """
        data = self.get_data()
        series_names = data[0][1:]
        serieses = []
        options = self.get_options()
        for i, name in enumerate(series_names):
            series = {"name": name, "data": column(data, i+1)[1:]}
            # If colors was passed then add color for the serieses
            if 'colors' in options and len(options['colors']) > i:
                series['color'] = options['colors'][i]
            serieses.append(series)
        serieses = self.add_series_options(serieses)
        return serieses

    def add_series_options(self, serieses):
        # hookpoint. You can subclass BaseHighCharts or its subclasses
        # and override this method to modify serieses.
        # eg: If you want to add dashStyle for a particular series of serieses
        # See http://api.highcharts.com/highcharts/ for options that can be added for series
        return serieses

    def get_series_json(self):
        serieses = self.get_series()
        return json.dumps(serieses, cls=JSONEncoderForHTML)

    def get_categories(self):
        """
        This would return [2004, 2005, 2006, 2007]
        """
        return column(self.get_data(), 0)[1:]

    def get_categories_json(self):
        categories = self.get_categories()
        return json.dumps(categories, cls=JSONEncoderForHTML)

    def get_title(self):
        title = self.get_options().get('title', {})
        if type(title) == str:
            title = {'text': title}
        return title

    def get_title_json(self):
        title = self.get_title()
        return json.dumps(title, cls=JSONEncoderForHTML)

    def get_subtitle(self):
        subtitle = self.get_options().get('subtitle', {})
        if type(subtitle) == str:
            subtitle = {'text': subtitle}
        return subtitle

    def get_subtitle_json(self):
        subtitle = self.get_subtitle()
        return json.dumps(subtitle, cls=JSONEncoderForHTML)

    def get_chart(self):
        chart = self.get_options().get('chart', {})
        chart['type'] = self.get_chart_type()
        return chart

    def get_chart_json(self):
        chart = self.get_chart()
        return json.dumps(chart, cls=JSONEncoderForHTML)

    def get_x_axis(self):
        x_axis = self.get_options().get('xAxis', {})
        if not 'categories' in x_axis:
            x_axis['categories'] = self.get_categories()
        if not 'title' in x_axis:
            x_axis['title'] = {}
        if not 'text' in x_axis['title']:
            x_axis['title']['text'] = self.get_x_axis_title()
        return x_axis

    def get_x_axis_json(self):
        x_axis = self.get_x_axis()
        return json.dumps(x_axis, cls=JSONEncoderForHTML)

    def get_y_axis(self):
        y_axis = self.get_options().get('yAxis', {})
        return y_axis

    def get_y_axis_json(self):
        y_axis = self.get_y_axis()
        return json.dumps(y_axis, cls=JSONEncoderForHTML)

    def get_tooltip(self):
        tooltip = self.get_options().get('tooltip', {})
        return tooltip

    def get_tooltip_json(self):
        tooltip = self.get_tooltip()
        return json.dumps(tooltip, cls=JSONEncoderForHTML)

    def get_x_axis_title(self):
        return self.get_data()[0][0]

class LineChart(BaseHighCharts):
    def get_chart_type(self):
        return "line"

class BarChart(BaseHighCharts):
    def get_chart_type(self):
        return "bar"

class ColumnChart(BaseHighCharts):
    def get_chart_type(self):
        return "column"

class ColumnLineChart(BaseHighCharts):
    """
    First series will be plotted as column
    Every subsequent series will be plotted as line
    """

    def get_series(self):
        data = self.get_data()
        serieses = []
        # TODO: Add color ability
        serieses.append({"name": data[0][1], "data": column(data, 1)[1:], "type": "column"})
        series_names = data[0][2:]
        for i, name in enumerate(series_names):
            serieses.append({"name": name, "data": column(data, i+2)[1:], "type": "line"})
        return serieses

    def get_chart_type(self):
        # TODO: This is a placeholder so that get_chart() doesn't fail. Think how we can fix this.
        return "column_line"

class LineColumnChart(BaseHighCharts):
    """
    First series will be plotted as line
    Every subsequent series will be plotted as column
    """

    def get_series(self):
        data = self.get_data()
        serieses = []
        # TODO: Add color ability
        serieses.append({"name": data[0][1], "data": column(data, 1)[1:], "type": "line"})
        series_names = data[0][2:]
        for i, name in enumerate(series_names):
            serieses.append({"name": name, "data": column(data, i+2)[1:], "type": "column"})
        return serieses

    def get_chart_type(self):
        return "line_column"

class PieChart(BaseHighCharts):
    def get_series(self):
        data = self.get_data()
        series_names = data[0][1:]
        serieses = []
        for i, name in enumerate(series_names):
            # TODO: Add color ability
            series = {"name": name, "data": pie_column(data, i+1)[1:]}
            serieses.append(series)
        return serieses

    def get_chart_type(self):
        return "pie"

class AreaChart(BaseHighCharts):
    def get_chart_type(self):
        return "area"

class DonutChart(PieChart):
    def get_js_template(self):
        return "graphos/highcharts/js_donut.html"

    def get_chart(self):
        chart = super(DonutChart, self).get_chart()
        chart['options3d'] = {'enabled': True, 'alpha': 45}
        return chart

    def get_plot_options(self):
        plot_options = self.get_options().get('plotOptions', {})
        plot_options['pie'] = {'innerSize': 100, 'depth': 45}
        return plot_options

    def get_plot_options_json(self):
        plot_options = self.get_plot_options()
        return json.dumps(plot_options, cls=JSONEncoderForHTML)

class ScatterChart(BaseHighCharts):
    def get_chart_type(self):
        return "scatter"

class LogarithmicChart(BaseHighCharts):
    def get_series(self):
        data = super(LogarithmicChart, self).get_series()
        data = data[0].get('data')
        return data

    def get_js_template(self):
        return "graphos/highcharts/js_log.html"

    def get_chart_type(self):
        return "log_chart"

class MultiAxisChart(BaseHighCharts):
    # TODO: This should be renamed dual axis, its not multi axis
    # It will break with more than two serieses
    def get_series(self):
        serieses = super(MultiAxisChart, self).get_series()
        chart_types = ['column', 'spline']
        # Make series 0 as column and series 1 as line
        for i, series in enumerate(serieses):
            if i == 0:
                series['yAxis'] = 1
            series['type'] = chart_types[i]
        return serieses

    def get_y_axis(self):
        y_axis = super(MultiAxisChart, self).get_y_axis()
        # This is overriding any thing set in yAxis. Fix
        y_axis = []
        y_axis.append({'title': {'text': self.get_series()[1]['name']}})
        y_axis.append({'title': {'text': self.get_series()[0]['name']}, 'opposite': True})
        return y_axis

    def get_chart_type(self):
        return "multi_axis"

class HighMap(BaseHighCharts):
    """docstring for HighMaps"""
    def __init__(self, *args, **kwargs):
        super(HighMap, self).__init__(*args, **kwargs)
        if type(self.get_data()[1][1]) in [int, float, long, Decimal]: # TODO: It could be any numeric, not just int
            self.series_type = 'single_series'
        else:
            self.series_type = 'multi_series'

    def get_series(self):
        # Currently graphos highmap only work with two columns, essentially that means only one series
        # That's why you see kv[1] and nothing beyond kv[1]
        # Can highcharts maps make sense for multiple serieses?
        """
        Different serieses should come up based on different data formats passed.
            1. Single series
                This would be a choropleth map where the color intensity of different regions/polygons
                differ based on the integer values in series. Two things are important here
                    a: It works with a colorAxis
                    b: First series i.e second column of tabular data must be integer.
            2. Multiple series
                Example
                State     Winner    Seats
                Orissa    BJP       5
                Bihar     RJD       10
                Assam     BJP       7
                Meghalaya AAP       12
                Manipur   AAP       4
                Punjab    AAP       4

                In this case all states won by AAP make up one series and will be colored in a particular color.
                Then all states won by BJP will be colored in a particular color. This color will be different from AAP color.
                But colorAxis doesn't make sense here. It's not a choropleth map.
                Graphos internally finds out all the distinct entries of second column of tabular data and created different serieses for different states.
        """
        if self.series_type == 'single_series':
            serieses = self.calculate_single_series()
        else:
            serieses = self.calculate_multi_series()
        return serieses

    def calculate_multi_series(self):
        data = self.get_data()[1:]
        name_to_regions_dict = defaultdict(list)
        second_column_onwards_names = self.get_data()[0][2:]
        chart_type = self.get_chart_type()
        for row in data:
            series_name = row[1]
            # Create a dictionary of format {'code': 'Orissa', 'Seats': 5}
            d = {'code': row[0]}
            second_column_onwards = row[2:]
            second_column_onwards_dict = dict(zip(second_column_onwards_names, second_column_onwards))
            # If it is a mapbubble, add 'z' based on some key
            if chart_type == 'mapbubble':
                zKey = self.get_options().get('zKey')
                if zKey:
                    d['z'] = second_column_onwards_dict[zKey]
            d.update(second_column_onwards_dict)
            name_to_regions_dict[series_name].append(d)
        serieses = []
        join_by = self.get_options().get('joinBy', 'hc-key')
        i = 0
        colors = self.get_options().get('colors', None)
        for series_name, regions in name_to_regions_dict.items():
            series = {}
            series['name'] = series_name
            series['data'] = regions
            series['joinBy'] = [join_by, 'code']
            #series['type'] = chart_type
            serieses.append(series)
            if colors and len(colors) > i:
                series['color'] = colors[i]
            i += 1
        if chart_type == 'mapbubble':
            just_for_sake_series = {}
            just_for_sake_series['name'] = 'Regions'
            just_for_sake_series['type'] = 'map'
            serieses.insert(0, just_for_sake_series)
        return serieses

    def calculate_single_series(self):
        data = self.get_data()[1:]
        first_series = {}
        options = self.get_options()
        first_series['data'] = []
        chart_type = self.get_chart_type()
        for i, kv in enumerate(data):
            if chart_type == 'mapbubble':
                region_detail = {'code': kv[0], 'z': kv[1]}
            elif chart_type == 'map':
                region_detail = {'code': kv[0], 'value': kv[1]}
            first_series['data'].append(region_detail)
        join_by = self.get_options().get('joinBy', 'hc-key')
        first_series['joinBy'] = [join_by, 'code']
        first_series['name'] = self.get_series_name()
        first_series['type'] = self.get_chart_type()
        serieses = []
        serieses.append(first_series)
        if chart_type == 'mapbubble':
            just_for_sake_series = {}
            just_for_sake_series['name'] = 'Regions'
            just_for_sake_series['type'] = 'map'
            serieses.insert(0, just_for_sake_series)
        return serieses

    def get_js_template(self):
        if self.series_type == 'single_series':
            return "graphos/highcharts/js_highmaps.html"
        else:
            return "graphos/highcharts/js_highmaps_multi_series.html"

    def get_map(self):
        # return "custom/world"
        # return "countries/us/custom/us-all-territories"
        return self.get_options().get('map_area', 'custom/world')

    def get_series_name(self):
        return self.get_data()[0][1]

    def get_color_axis(self):
        color_axis = self.get_options().get('colorAxis', {})
        return color_axis

    def get_color_axis_json(self):
        color_axis = self.get_color_axis()
        return json.dumps(color_axis, cls=JSONEncoderForHTML)

    def get_plot_options(self):
        plot_options = self.get_options().get('plotOptions', {})
        if not 'map' in plot_options:
            plot_options['map'] = {}
        if not 'mapbubble' in plot_options:
            plot_options['mapbubble'] = {}
        return plot_options

    def get_plot_options_json(self):
        plot_options = self.get_plot_options()
        return json.dumps(plot_options, cls=JSONEncoderForHTML)

    def get_chart_type(self):
        # If you are using mapbubble, ensure you don't set allAreas to False.
        # Also if you are setting mapbubble for a multi series chart, then probably you should set zKey too to get different bubble sizes.
        return self.get_options().get("map_type", "map")

def column(matrix, i):
    return [row[i] for row in matrix]

def pie_column(matrix, i):
    return [{'name':row[0],'y':row[i]} for row in matrix]
<|endoftext|>


<commit_before>#!/usr/bin/env python

"""
$Id$

This file is part of the sqlmap project, http://sqlmap.sourceforge.net.

Copyright (c) 2007-2010 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 Daniele Bellucci <daniele.bellucci@gmail.com>

sqlmap is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation version 2 of the License.

sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
details.

You should have received a copy of the GNU General Public License along
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
"""

import os
import sys
import time
import traceback
import warnings

warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning)

try:
    import psyco
    psyco.full()
    psyco.profile()
except ImportError, _:
    pass

from lib.controller.controller import start
from lib.core.common import banner
from lib.core.common import profile
from lib.core.common import setPaths
from lib.core.common import weAreFrozen
from lib.core.data import conf
from lib.core.data import logger
from lib.core.data import paths
from lib.core.exception import exceptionsTuple
from lib.core.exception import unhandledException
from lib.core.option import init
from lib.parse.cmdline import cmdLineParser

def modulePath():
    """
    This will get us the program's directory, even if we are frozen
    using py2exe
    """

    if weAreFrozen():
        return os.path.dirname(unicode(sys.executable, sys.getfilesystemencoding()))
    else:
        return os.path.dirname(os.path.realpath(__file__))

def main():
    """
    Main function of sqlmap when running from command line.
    """

    paths.SQLMAP_ROOT_PATH = modulePath()
    setPaths()

    banner()
    cmdLineOptions = cmdLineParser()

    print "[*] starting at: %s\n" % time.strftime("%X")

    try:
        init(cmdLineOptions)
        if not conf.profile:
            start()
        else:
            profile()
    except exceptionsTuple, e:
        e = str(e)
        logger.error(e)

    except KeyboardInterrupt:
        print
        errMsg = "user aborted"
        logger.error(errMsg)

    except EOFError:
        print
        errMsg = "exit"
        logger.error(errMsg)

    except:
        print
        errMsg = unhandledException()
        logger.error(errMsg)
        traceback.print_exc()

    print "\n[*] shutting down at: %s\n" % time.strftime("%X")

if __name__ == "__main__":
    main()
<commit_msg>minor refactoring<commit_after>#!/usr/bin/env python

"""
$Id$

This file is part of the sqlmap project, http://sqlmap.sourceforge.net.

Copyright (c) 2007-2010 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 Daniele Bellucci <daniele.bellucci@gmail.com>

sqlmap is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation version 2 of the License.

sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
details.

You should have received a copy of the GNU General Public License along
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
"""

import os
import sys
import time
import traceback
import warnings

warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning)

try:
    import psyco
    psyco.full()
    psyco.profile()
except ImportError, _:
    pass

from lib.controller.controller import start
from lib.core.common import banner
from lib.core.common import profile
from lib.core.common import setPaths
from lib.core.common import weAreFrozen
from lib.core.data import conf
from lib.core.data import logger
from lib.core.data import paths
from lib.core.exception import exceptionsTuple
from lib.core.exception import unhandledException
from lib.core.option import init
from lib.parse.cmdline import cmdLineParser

def modulePath():
    """
    This will get us the program's directory, even if we are frozen
    using py2exe
    """

    if weAreFrozen():
        return os.path.dirname(unicode(sys.executable, sys.getfilesystemencoding()))
    else:
        return os.path.dirname(os.path.realpath(__file__))

def main():
    """
    Main function of sqlmap when running from command line.
    """

    paths.SQLMAP_ROOT_PATH = modulePath()
    setPaths()

    banner()
    cmdLineOptions = cmdLineParser()

    print "[*] starting at: %s\n" % time.strftime("%X")

    try:
        init(cmdLineOptions)
        if conf.profile:
            profile()
        else:
            start()
    except exceptionsTuple, e:
        e = str(e)
        logger.error(e)

    except KeyboardInterrupt:
        print
        errMsg = "user aborted"
        logger.error(errMsg)

    except EOFError:
        print
        errMsg = "exit"
        logger.error(errMsg)

    except:
        print
        errMsg = unhandledException()
        logger.error(errMsg)
        traceback.print_exc()

    print "\n[*] shutting down at: %s\n" % time.strftime("%X")

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2013-2021 GEM Foundation
#
# OpenQuake is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenQuake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OpenQuake. If not, see <http://www.gnu.org/licenses/>.

"""
Module exports :class:`VanHoutteEtAl2018RSD`
"""
import numpy as np

from openquake.hazardlib.gsim.base import CoeffsTable, GMPE
from openquake.hazardlib import const
from openquake.hazardlib.imt import RSD575

class VanHoutteEtAl2018RSD(GMPE):
    """
    Implements the GMPE of Van Houtte et al. (2018) for significant duration
    with 5 - 75 % Arias Intensity. doi:10.1785/0120170076. The oscillator
    duration model has not yet been implemented.
    """
    #: Supported tectonic region type is active shallow crust
    DEFINED_FOR_TECTONIC_REGION_TYPE = const.TRT.ACTIVE_SHALLOW_CRUST

    #: Supported intensity measure types are 5 - 75 % Arias
    #: significant duration
    DEFINED_FOR_INTENSITY_MEASURE_TYPES = set([RSD575])

    #: Supported intensity measure component is RotD50
    DEFINED_FOR_INTENSITY_MEASURE_COMPONENT = const.IMC.AVERAGE_HORIZONTAL

    #: Supported standard deviation types are total, inter and intra-event
    DEFINED_FOR_STANDARD_DEVIATION_TYPES = set([
        const.StdDev.TOTAL,
        const.StdDev.INTER_EVENT,
        const.StdDev.INTRA_EVENT
    ])

    #: Requires vs30
    REQUIRES_SITES_PARAMETERS = {'vs30'}

    #: Required rupture parameter is magnitude
    REQUIRES_RUPTURE_PARAMETERS = {'mag'}

    #: Required distance measure is closest distance to rupture
    REQUIRES_DISTANCES = {'rrup'}

    def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types):
        """
        See :meth:`superclass method
        <.base.GroundShakingIntensityModel.get_mean_and_stddevs>`
        for spec of input and result values.
        """
        C = self.COEFFS[imt]
        mean = (self.get_magnitude_term(C, rup.mag) +
                self.get_distance_term(C, dists.rrup, rup.mag) +
                self.get_site_amplification(C, sites.vs30))
        stddevs = self.get_stddevs(C, dists.rrup.shape, stddev_types)
        return mean, stddevs

    def get_magnitude_term(self, C, mag):
        """
        Returns linear magnitude scaling term
        """
        return C["b0"] + C["b1"] * (mag - 6) + C["b2"] * (mag - 6) ** 2

    def get_distance_term(self, C, rrup, mag):
        """
        Returns distance scaling term
        """
        fac = rrup > 100
        rmax100 = rrup.copy()
        rmax100[rmax100 > 100] = 100
        fr = C["b3"] * np.log(np.sqrt(
            rmax100 ** 2 + (np.exp(C["b4"] + C["b5"] * (mag - 6))) ** 2)) + \
            fac * (
            C["b6"] * np.log(np.sqrt(
                 rrup ** 2 + (np.exp(C["b4"] + C["b5"] * (mag - 6))) ** 2)) -
            C["b6"] * np.log(np.sqrt(
                100 ** 2 + (np.exp(C["b4"] + C["b5"] * (mag - 6))) ** 2))
            )
        return fr

    def get_site_amplification(self, C, vs30):
        """
        Returns linear site amplification term
        """
        return C["b7"] * np.log(vs30 / 1000)

    def get_stddevs(self, C, nsites, stddev_types):
        """
        Returns the standard deviations
        """
        stddevs = []
        zeros_array = np.zeros(nsites)
        for stddev in stddev_types:
            assert stddev in self.DEFINED_FOR_STANDARD_DEVIATION_TYPES
            if stddev == const.StdDev.TOTAL:
                stddevs.append(np.sqrt(C["tau"] ** 2. + C["phi"] ** 2.) +
                               zeros_array)
            elif stddev == const.StdDev.INTER_EVENT:
                stddevs.append(C["tau"] + zeros_array)
            elif stddev == const.StdDev.INTRA_EVENT:
                stddevs.append(C["phi"] + zeros_array)
        return stddevs

    COEFFS = CoeffsTable(sa_damping=5, table="""\
    imt          b0       b1      b2       b3      b4       b5       b6      b7     tau     phi
    rsd575  -1.7204   0.2272  0.0967   0.8870  2.7641   0.5777   1.1700 -0.1413  0.2270  0.4163
    """)
<commit_msg>Refactored vanhoutte_2018<commit_after># -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2013-2021 GEM Foundation
#
# OpenQuake is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenQuake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OpenQuake. If not, see <http://www.gnu.org/licenses/>.

"""
Module exports :class:`VanHoutteEtAl2018RSD`
"""
import numpy as np

from openquake.hazardlib.gsim.base import CoeffsTable, GMPE
from openquake.hazardlib import const
from openquake.hazardlib.imt import RSD575

def get_magnitude_term(C, mag):
    """
    Returns linear magnitude scaling term
    """
    return C["b0"] + C["b1"] * (mag - 6) + C["b2"] * (mag - 6) ** 2

def get_distance_term(C, rrup, mag):
    """
    Returns distance scaling term
    """
    fac = rrup > 100
    rmax100 = rrup.copy()
    rmax100[rmax100 > 100] = 100
    fr = C["b3"] * np.log(np.sqrt(
        rmax100 ** 2 + (np.exp(C["b4"] + C["b5"] * (mag - 6))) ** 2)) + \
        fac * (
        C["b6"] * np.log(np.sqrt(
             rrup ** 2 + (np.exp(C["b4"] + C["b5"] * (mag - 6))) ** 2)) -
        C["b6"] * np.log(np.sqrt(
            100 ** 2 + (np.exp(C["b4"] + C["b5"] * (mag - 6))) ** 2))
        )
    return fr

def get_site_amplification(C, vs30):
    """
    Returns linear site amplification term
    """
    return C["b7"] * np.log(vs30 / 1000)

def get_stddevs(C, nsites, stddev_types):
    """
    Returns the standard deviations
    """
    stddevs = []
    zeros_array = np.zeros(nsites)
    for stddev in stddev_types:
        if stddev == const.StdDev.TOTAL:
            stddevs.append(np.sqrt(C["tau"] ** 2. + C["phi"] ** 2.) +
                           zeros_array)
        elif stddev == const.StdDev.INTER_EVENT:
            stddevs.append(C["tau"] + zeros_array)
        elif stddev == const.StdDev.INTRA_EVENT:
            stddevs.append(C["phi"] + zeros_array)
    return stddevs

class VanHoutteEtAl2018RSD(GMPE):
    """
    Implements the GMPE of Van Houtte et al. (2018) for significant duration
    with 5 - 75 % Arias Intensity. doi:10.1785/0120170076. The oscillator
    duration model has not yet been implemented.
    """
    #: Supported tectonic region type is active shallow crust
    DEFINED_FOR_TECTONIC_REGION_TYPE = const.TRT.ACTIVE_SHALLOW_CRUST

    #: Supported intensity measure types are 5 - 75 % Arias
    #: significant duration
    DEFINED_FOR_INTENSITY_MEASURE_TYPES = set([RSD575])

    #: Supported intensity measure component is RotD50
    DEFINED_FOR_INTENSITY_MEASURE_COMPONENT = const.IMC.AVERAGE_HORIZONTAL

    #: Supported standard deviation types are total, inter and intra-event
    DEFINED_FOR_STANDARD_DEVIATION_TYPES = {
        const.StdDev.TOTAL, const.StdDev.INTER_EVENT, const.StdDev.INTRA_EVENT}

    #: Requires vs30
    REQUIRES_SITES_PARAMETERS = {'vs30'}

    #: Required rupture parameter is magnitude
    REQUIRES_RUPTURE_PARAMETERS = {'mag'}

    #: Required distance measure is closest distance to rupture
    REQUIRES_DISTANCES = {'rrup'}

    def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types):
        """
        See :meth:`superclass method
        <.base.GroundShakingIntensityModel.get_mean_and_stddevs>`
        for spec of input and result values.
        """
        C = self.COEFFS[imt]
        mean = (get_magnitude_term(C, rup.mag) +
                get_distance_term(C, dists.rrup, rup.mag) +
                get_site_amplification(C, sites.vs30))
        stddevs = get_stddevs(C, dists.rrup.shape, stddev_types)
        return mean, stddevs

    COEFFS = CoeffsTable(sa_damping=5, table="""\
    imt          b0       b1      b2       b3      b4       b5       b6      b7     tau     phi
    rsd575  -1.7204   0.2272  0.0967   0.8870  2.7641   0.5777   1.1700 -0.1413  0.2270  0.4163
    """)
<|endoftext|>