Skip to content

Commit 0593d5b

Browse files
authored
ARE-6139: sensitivity analysis enpoint wrapper (#49)
* python wrapper for sensitivity analsys and tests drafts * some updates to the tests * candidates filtering and supporting test * made parameterized test, added list of attributes
1 parent f10ce73 commit 0593d5b

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

analyzere/resources.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,17 @@ def candidate_metrics(self):
212212
resp = request('get', path)
213213
return convert_to_analyzere_object(resp)
214214

215+
def sensitivity_analysis(self, candidates=[]):
216+
# candidates can be only non negative integers
217+
candidates = list(filter(lambda x: isinstance(x, int) and x >= 0, candidates))
218+
if len(candidates) == 0:
219+
path = '{}/sensitivity_analysis'.format(self._get_path(self.id))
220+
else:
221+
path = '{}/sensitivity_analysis?candidates={}'.format(self._get_path(self.id),
222+
','.join(str(c) for c in candidates))
223+
resp = request('get', path)
224+
return convert_to_analyzere_object(resp)
225+
215226

216227
class OptimizationDomain(EmbeddedResource):
217228
pass

tests/test_base_resources.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,3 +911,49 @@ def test_initial_portfolio_metrics(self, reqmock):
911911
text='{"num": 1.0}')
912912
f = OptimizationView(id='abc123').initial_metrics()
913913
assert f.num == 1.0
914+
915+
sensitivity_text = """
916+
{"sensitivities": [
917+
{"normalized_interquartile_range": 0.25, "min": 0.0, "normalized_standard_deviation": 0.29,
918+
"initial_share": 0.18, "hist": { "0.05": 5, "0.1": 0, "0.15": 0, "0.2": 0, "0.25": 0, "0.3": 9, "0.35": 0,
919+
"0.4": 0, "0.45": 0, "0.5": 3, "0.55": 0, "0.6": 5, "0.65": 0, "0.7": 3, "0.75": 0, "0.8": 3, "0.85": 2,
920+
"0.9": 4, "0.95": 2, "1.0": 64}, "mean": 0.81, "max": 1.0, "ref_id": "layer2"
921+
},
922+
{ "normalized_interquartile_range": 0.71, "min": 0.0, "normalized_standard_deviation": 0.35,
923+
"initial_share": 0.08, "hist": {"0.05": 36, "0.1": 0, "0.15": 8, "0.2": 1, "0.25": 1, "0.3": 3,
924+
"0.35": 2, "0.4": 3, "0.45": 0, "0.5": 0, "0.55": 8, "0.6": 0, "0.65": 12, "0.7": 0, "0.75": 1,
925+
"0.8": 10, "0.85": 0, "0.9": 7, "0.95": 0, "1.0": 8}, "mean": 0.37, "max": 1.0, "ref_id": "layer1" }
926+
] } """
927+
928+
required_attributes = ['hist', 'min', 'max', 'mean', 'normalized_standard_deviation',
929+
'normalized_interquartile_range', 'ref_id']
930+
931+
@pytest.mark.parametrize("get_string, candidates, expected_len", [
932+
('https://api/optimization_views/abc_id/sensitivity_analysis', [], 2),
933+
('https://api/optimization_views/abc_id/sensitivity_analysis?candidates=0,2,5', [0, 2, 5], 2),
934+
('https://api/optimization_views/abc_id/sensitivity_analysis?candidates=0,2,5', [0, 2, 5, 'a', 1.1, -2], 2)
935+
])
936+
def test_sensitivity_analysis_with_candidates(self, reqmock, candidates, expected_len, get_string):
937+
# list of candidates should be translated to the correct api request
938+
reqmock.get('https://api/optimization_views/abc_id',
939+
status_code=200, text='{"id":"abc_id"}')
940+
ov = OptimizationView.retrieve('abc_id')
941+
reqmock.get(get_string,
942+
status_code=200, text=TestOptimizationResource.sensitivity_text)
943+
r = ov.sensitivity_analysis(candidates=candidates)
944+
assert hasattr(r, 'sensitivities')
945+
assert len(r.sensitivities) == expected_len
946+
for i in range(len(r.sensitivities)):
947+
for attribute in TestOptimizationResource.required_attributes:
948+
assert hasattr(r.sensitivities[i], attribute)
949+
950+
def test_sensitivity_analysis_empty(self, reqmock):
951+
# result can be an empty list
952+
reqmock.get('https://api/optimization_views/abc_id',
953+
status_code=200, text='{"id":"abc_id"}')
954+
ov = OptimizationView.retrieve('abc_id')
955+
reqmock.get('https://api/optimization_views/abc_id/sensitivity_analysis',
956+
status_code=200, text='{"sensitivities": []}')
957+
r = ov.sensitivity_analysis()
958+
assert hasattr(r, 'sensitivities')
959+
assert len(r.sensitivities) == 0

0 commit comments

Comments
 (0)