def parse_obs(self, elem): values = self._parse(elem) dsd = self._get_current(DataStructureDefinition) # Attached attributes aa = values.pop('attributes', {}) if 'obskey' in values: key = values.pop('obskey') elif 'obsdimension' in values: od = values.pop('obsdimension') dim = self._obs_dim.id if len(od) == 2: assert od['id'] == dim, (values, dim) key = Key(**{dim: od['value']}, dsd=dsd) if len(values): value = values.pop('obsvalue', None) else: # StructureSpecificData message—all information stored as XML # attributes of the <Observation>. attr = copy(elem.attrib) # Value of the observation value = attr.pop('OBS_VALUE', None) # Use the DSD to separate dimensions and attributes key = Key(**attr, dsd=dsd) # Remove attributes from the Key to be attached to the Observation aa.update(key.attrib) key.attrib = {} assert len(values) == 0, values return Observation(dimension=key, value=value, attached_attribute=aa)
def _make_obs(self, key, data): """Create an Observation from tuple *key* and pd.Series *data.""" # Create the Key key = Key( {dim: value for dim, value in zip(self._data.index.names, key)}) attrs = {} # Handle columns of ._data for col, value in data.items(): try: # A tuple column label is ('attr_obs', attr_id) group, attr_id = col except ValueError: # Not a tuple → the 'value' column, handled below continue if group == 'attr_obs': # Create a DataAttribute attrs[attr_id] = AttributeValue( value_for=DataAttribute(id=attr_id), value=value) return Observation(dimension=key, value=data['value'], attached_attribute=attrs)
def test_key(): # Construct with a dict k1 = Key({'foo': 1, 'bar': 2}) # Construct with kwargs k2 = Key(foo=1, bar=2) # Results are __eq__ each other assert k1 == k2 # Doing both is an error with raises(ValueError): Key({'foo': 1}, bar=2) # __len__ assert len(k1) == 2 # __contains__: symmetrical if keys are identical assert k1 in k2 assert k2 in k1 assert Key(foo=1) in k1 assert k1 not in Key(foo=1) # Set and get using item convenience k1['baz'] = 3 # bare value is converted to a KeyValue assert k1['foo'] == 1 # __str__ assert str(k1) == '(foo=1, bar=2, baz=3)' # copying: returns a new object equal to the old one k2 = k1.copy() assert id(k1) != id(k2) and k1 == k2 # copy with changes k2 = Key(foo=1, bar=2).copy(baz=3) assert id(k1) != id(k2) and k1 == k2 # __add__: Key with something else with raises(NotImplementedError): k1 + 4 # Two Keys k2 = Key(foo=1) + Key(bar=2) assert k2 == k1 # __radd__: adding a Key to None produces a Key assert None + k1 == k1 # anything else is an error with raises(NotImplementedError): 4 + k1 # get_values(): preserve ordering assert k1.get_values() == (1, 2, 3)