Skip to content

Commit 9d86800

Browse files
committed
Add DataDict to Fields and add find feature on DataDict
1 parent caccc4b commit 9d86800

5 files changed

Lines changed: 56 additions & 152 deletions

File tree

opus/data.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ def append(self, key, value):
3131
def load(self, dict):
3232
self._data = dict
3333

34+
def find(self, keyword):
35+
keyword = keyword.lower()
36+
keys = []
37+
for key in self.keys():
38+
if keyword in key.lower():
39+
keys.append(key)
40+
if len(keys) == 0:
41+
return None
42+
return keys
43+
44+
3445
class Data(DataDict):
3546
def __init__(self, json):
3647
DataDict.__init__(self)

opus/fields.py

Lines changed: 22 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# -*- coding: utf-8 -*-
22
import re
33

4+
from .data import DataDict
5+
46
def splitKey(key):
57
'''Split from first uppercase word (ie., `body`)'''
68
body = re.findall('[^a-z]+', key)[0]
@@ -16,12 +18,15 @@ def __init__(self, field, json):
1618
self._json = json
1719
self.field = field
1820
self.label = json['label']
19-
21+
2022
def __repr__(self):
2123
if self.desc is not None:
22-
return '`{}` -> {}\n{}\n_More info_: {}'.format(self.field, self.label, self.desc, self.url)
24+
return '{} ({}):\n => {}\n {}'.format(self.label, self.field, self.desc, self.url)
2325
else:
24-
return '`{}` -> {}'.format(self.field, self.label)
26+
return '{}: ({})'.format(self.label, self.field)
27+
28+
def __str__(self):
29+
return self.label
2530

2631
@property
2732
def desc(self):
@@ -45,85 +50,35 @@ def url(self):
4550
return url
4651

4752

48-
class Fields(object):
53+
class Fields(DataDict):
4954
def __init__(self, json):
55+
DataDict.__init__(self)
5056
self._json = json
51-
self._data = {'GLOBAL': GlobalField()}
57+
self.append('GLOBAL', GlobalField())
5258
for key, value in json.items():
53-
5459
if 'surfacegeometry' in key:
5560
try:
5661
body, field = splitKey(key)
57-
if body not in self._data:
58-
self._data[body] = SurfaceGeometry(body)
59-
self._data[body].add(field, Field(key, value))
62+
if body not in self.keys():
63+
self.append(body, SurfaceGeometry(body))
64+
self[body].append(field, Field(key, value))
6065
except IndexError:
61-
self._data['GLOBAL'].add(key.lower(), Field(key, value))
66+
self['GLOBAL'].append(key.lower(), Field(key, value))
6267
else:
63-
self._data['GLOBAL'].add(key.lower(), Field(key, value))
68+
self['GLOBAL'].append(key.lower(), Field(key, value))
6469

6570
def __repr__(self):
66-
return 'OPUS API list of all fields ({})'.format(len(self))
67-
68-
def __len__(self):
69-
return len(self._json)
70-
71-
def __getitem__(self, attr):
72-
return self._data[attr.upper()]
73-
74-
def __iter__(self):
75-
return iter(self._data)
76-
77-
def keys(self):
78-
return self._data.keys()
79-
80-
def items(self):
81-
return self._data.items()
82-
83-
def values(self):
84-
return self._data.values()
71+
return 'OPUS API list of all fields available ({}):\n'.format(len(self)) + \
72+
'\n'.join(' - {}'.format(key) for key in self)
8573

8674

87-
class GlobalField(object):
75+
class GlobalField(DataDict):
8876
def __init__(self):
89-
self._fields = {}
77+
DataDict.__init__(self)
9078

9179
def __repr__(self):
9280
return 'OPUS API Global fields ({}):\n'.format(len(self)) + \
93-
'\n'.join(
94-
' - {} ({})'.format(value.label, key) for key, value in self.items()
95-
)
96-
97-
def __len__(self):
98-
return len(self._fields)
99-
100-
def __getitem__(self, attr):
101-
return self._fields[attr]
102-
103-
def __iter__(self):
104-
return iter(self._fields)
105-
106-
def keys(self):
107-
return self._fields.keys()
108-
109-
def items(self):
110-
return self._fields.items()
111-
112-
def values(self):
113-
return self._fields.values()
114-
115-
def add(self, name, field):
116-
self._fields[name] = field
117-
118-
def find(self, keyword):
119-
keyword = keyword.lower()
120-
keys = []
121-
for key, value in self.items():
122-
if keyword in value.label.lower():
123-
keys.append(key)
124-
if len(keys) == 0:
125-
return None
126-
return keys
81+
'\n'.join(' - {} ({})'.format(value, key) for key, value in self.items())
12782

12883

12984
class SurfaceGeometry(GlobalField):
@@ -133,6 +88,4 @@ def __init__(self, body):
13388

13489
def __repr__(self):
13590
return 'OPUS API Surface Geometry fields ({}) for `{}`:\n'.format(len(self), self.body.title()) + \
136-
'\n'.join(
137-
' - {} ({})'.format(value.label, key) for key, value in self.items()
138-
)
91+
'\n'.join(' - {} ({})'.format(value, key) for key, value in self.items())

tests/test_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def test_api_fields(api):
309309
assert responses.calls[0].request.url == 'http://localhost/fields.json'
310310
assert responses.calls[0].response.text == fields
311311

312-
assert len(resp) == 3971
312+
assert len(resp) == 304
313313

314314

315315
@responses.activate

tests/test_data.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ def test_data_dict(data_dict):
3030
assert data_dict['abc'] == 'foo'
3131
assert data_dict['def'] == 'bar'
3232

33+
def test_data_dict_find(data_dict):
34+
data_dict.load({'abc': 'foo', 'def': 'bar'})
35+
assert 'abc' in data_dict.find('AB')
36+
assert data_dict.find('ac') is None
3337

3438
def test_data_dict_iter(data_dict):
3539
data_dict.append('abc', 'foo')

tests/test_fields.py

Lines changed: 18 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -21,100 +21,36 @@ def fields():
2121
def field_empty():
2222
return Field('empty', {'label': 'Empty', 'more_info': {'def': False, 'more_info': False}})
2323

24+
def test_split_key():
25+
assert splitKey('surfacegeometryTITANIAsubobserverIAUlongitude') == ('TITANIA', 'subobserverIAUlongitude')
26+
2427
def test_field_repr(field):
25-
assert repr(field) == \
26-
'`target` -> Intended Target Name\n' + \
27-
'The target_name element identifies a target. The target may be a planet, ' + \
28-
'satellite,ring,region, feature, asteroid or comet. See target_type.\n' + \
29-
'_More info_: http://pds-rings.seti.org/dictionary/index.php?term=TARGET_NAME&context=PSDD'
28+
assert repr(field) == 'Intended Target Name (target):\n' + \
29+
' => The target_name element identifies a target. The target may be a planet, satellite,ring,region, feature, asteroid or comet. See target_type.\n' + \
30+
' http://pds-rings.seti.org/dictionary/index.php?term=TARGET_NAME&context=PSDD'
31+
assert str(field) == 'Intended Target Name'
3032

3133
def test_field_empty(field_empty):
32-
assert repr(field_empty) == '`empty` -> Empty'
34+
assert repr(field_empty) == 'Empty: (empty)'
3335
assert field_empty.url == None
3436

3537
def test_field_err(field):
3638
with pytest.raises(KeyError):
3739
Field('abc', {})
3840

39-
def test_split_key():
40-
assert splitKey('surfacegeometryTITANIAsubobserverIAUlongitude') == ('TITANIA', 'subobserverIAUlongitude')
41-
4241
def test_fields_repr(fields):
43-
assert repr(fields) == 'OPUS API list of all fields (3971)'
42+
r = repr(fields)
43+
assert 'OPUS API list of all fields available (304)' in r
44+
assert 'GLOBAL' in r
4445

45-
def test_fields_iter(fields):
46-
assert 'GLOBAL' in fields
47-
48-
for key, value in fields.items():
49-
assert fields[key] == value
50-
break
51-
52-
def test_fields_keys_values(fields):
53-
keys = fields.keys()
54-
values = fields.values()
55-
assert len(keys) == 304
56-
assert len(values) == 304
57-
assert 'GLOBAL' in keys
58-
assert 'JUPITER' in keys
59-
60-
6146
def test_global_field_repr(fields):
62-
assert isinstance(repr(fields['global']), str)
63-
assert len(fields['global'].values()) == 234
47+
r = repr(fields['GLOBAL'])
48+
assert 'OPUS API Global fields (234)' in r
49+
assert 'Lesser Size in Pixels' in r
6450

65-
def test_global_field_iter(fields):
66-
assert 'line1' in fields['global']
67-
assert repr(fields['global']['line1']) == '`LINE1` -> Line'
6851

6952
def test_surface_geometry_repr(fields):
70-
if six.PY3:
71-
assert repr(fields['jupiter']) == \
72-
'OPUS API Surface Geometry fields (31) for `Jupiter`:\n' + \
73-
' - Solar Hour Angle (solarhourangle)\n' + \
74-
' - Body Center Resolution (centerresolution)\n' + \
75-
' - Observed Phase Angle 2 (phase2)\n' + \
76-
' - Observed Phase Angle (phase1)\n' + \
77-
' - Coarsest Observed Resolution (coarsestresolution1)\n' + \
78-
' - Sub-Solar IAU West Longitude (subsolarIAUlongitude)\n' + \
79-
' - Observed Incidence Angle (incidence1)\n' + \
80-
' - D Solar Hour Angle (dsolarhourangle)\n' + \
81-
' - Observed Planetocentric Latitude 2 (planetocentriclatitude2)\n' + \
82-
' - Body Center Distance (centerdistance)\n' + \
83-
' - D Observer Longitude (dObserverlongitude)\n' + \
84-
' - Sub-Solar Planetographic Latitude (subsolarplanetographiclatitude)\n' + \
85-
' - Sub-Observer Planetocentric Latitude (subobserverplanetocentriclatitude)\n' + \
86-
' - Observed Planetographic Latitude (planetographiclatitude1)\n' + \
87-
' - Observed Planetographic Latitude 2 (planetographiclatitude2)\n' + \
88-
' - Sub-Solar Planetocentric Latitude (subsolarplanetocentriclatitude)\n' + \
89-
' - Observed Emission Angle (emission1)\n' + \
90-
' - Observed Emission Angle 2 (emission2)\n' + \
91-
' - Observed Incidence Angle 2 (incidence2)\n' + \
92-
' - Sub-Observer Planetographic Latitude (subobserverplanetographiclatitude)\n' + \
93-
' - Coarsest Observed Resolution 2 (coarsestresolution2)\n' + \
94-
' - Sub-Observer IAU West Longitude (subobserverIAUlongitude)\n' + \
95-
' - Observed Distance to Surface 2 (rangetobody2)\n' + \
96-
' - Observed Distance to Surface (rangetobody1)\n' + \
97-
' - Observed Local Time 2 (solarhourangle2)\n' + \
98-
' - Observed Local Time (solarhourangle1)\n' + \
99-
' - Phase Angle at Body Center (centerphaseangle)\n' + \
100-
' - Observed Planetocentric Latitude (planetocentriclatitude1)\n' + \
101-
' - D Iau West Longitude (dIAUwestlongitude)\n' + \
102-
' - Finest Observed Resolution 2 (finestresolution2)\n' + \
103-
' - Finest Observed Resolution (finestresolution1)'
104-
else:
105-
assert isinstance(repr(fields['jupiter']), str)
106-
107-
def test_surface_geometry_keys(fields):
108-
keys = fields['jupiter'].keys()
109-
assert len(keys) == 31
110-
assert 'solarhourangle' in keys
111-
112-
113-
def test_surface_geometry_find(fields):
114-
found = fields['jupiter'].find('phase')
115-
assert len(found) == 3
116-
assert 'phase1' in found
117-
assert 'phase2' in found
118-
assert 'centerphaseangle' in found
119-
120-
assert fields['jupiter'].find('target') == None
53+
r = repr(fields['TITAN'])
54+
assert 'OPUS API Surface Geometry fields (31) for `Titan`' in r
55+
assert 'Sub-Solar IAU West Longitude' in r
56+

0 commit comments

Comments
 (0)