Repository: microsoft/recommenders
Issue: [BUG] error in unit test nni

### Description
<!--- Describe your issue/bug/request in detail -->
```
$ pytest tests/unit/test_nni_utils.py

=========================================================================== test session starts ===========================================================================
platform linux -- Python 3.6.10, pytest-5.4.3, py-1.8.1, pluggy-0.13.1
rootdir: /home/miguel/repos/Recommenders
collected 11 items

tests/unit/test_nni_utils.py ..........F                                                                                                                            [100%]

================================================================================ FAILURES =================================================================================
_____________________________________________________________________________ test_get_trials _____________________________________________________________________________

    @pytest.mark.skipif(sys.platform == "win32", reason="nni not installable on windows")
    def test_get_trials():
        with TemporaryDirectory() as tmp_dir1, TemporaryDirectory() as tmp_dir2:
            mock_trials = [
                {
                    "finalMetricData": [{"data": '{"rmse":0.8,"default":0.3}'}],
                    "logPath": "file://localhost:{}".format(tmp_dir1),
                },
                {
                    "finalMetricData": [{"data": '{"rmse":0.9,"default":0.2}'}],
                    "logPath": "file://localhost:{}".format(tmp_dir2),
                },
            ]
            metrics1 = {"rmse": 0.8, "precision_at_k": 0.3}
            with open(os.path.join(tmp_dir1, "metrics.json"), "w") as f:
                json.dump(metrics1, f)
            params1 = {
                "parameter_id": 1,
                "parameter_source": "algorithm",
                "parameters": {"n_factors": 100, "reg": 0.1},
            }
            with open(os.path.join(tmp_dir1, "parameter.cfg"), "w") as f:
                json.dump(params1, f)
            metrics2 = {"rmse": 0.9, "precision_at_k": 0.2}
            with open(os.path.join(tmp_dir2, "metrics.json"), "w") as f:
                json.dump(metrics2, f)
            params2 = {
                "parameter_id": 2,
                "parameter_source": "algorithm",
                "parameters": {"n_factors": 50, "reg": 0.02},
            }
            with open(os.path.join(tmp_dir2, "parameter.cfg"), "w") as f:
                json.dump(params2, f)

            with patch(
                "requests.get", side_effect=lambda url: mocked_trials_get(url, mock_trials)
            ):
                trials, best_metrics, best_params, best_trial_path = get_trials(
>                   optimize_mode="maximize"
                )

tests/unit/test_nni_utils.py:204:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
reco_utils/tuning/nni/nni_utils.py:117: in get_trials
    for trial in all_trials
reco_utils/tuning/nni/nni_utils.py:117: in <listcomp>
    for trial in all_trials
../../anaconda/envs/reco_full/lib/python3.6/ast.py:85: in literal_eval
    return _convert(node_or_string)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

node = {'default': 0.3, 'rmse': 0.8}

    def _convert(node):
        if isinstance(node, Constant):
            return node.value
        elif isinstance(node, (Str, Bytes)):
            return node.s
        elif isinstance(node, Num):
            return node.n
        elif isinstance(node, Tuple):
            return tuple(map(_convert, node.elts))
        elif isinstance(node, List):
            return list(map(_convert, node.elts))
        elif isinstance(node, Set):
            return set(map(_convert, node.elts))
        elif isinstance(node, Dict):
            return dict((_convert(k), _convert(v)) for k, v
                        in zip(node.keys, node.values))
        elif isinstance(node, NameConstant):
            return node.value
        elif isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)):
            operand = _convert(node.operand)
            if isinstance(operand, _NUM_TYPES):
                if isinstance(node.op, UAdd):
                    return + operand
                else:
                    return - operand
        elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)):
            left = _convert(node.left)
            right = _convert(node.right)
            if isinstance(left, _NUM_TYPES) and isinstance(right, _NUM_TYPES):
                if isinstance(node.op, Add):
                    return left + right
                else:
                    return left - right
>       raise ValueError('malformed node or string: ' + repr(node))
E       ValueError: malformed node or string: {'rmse': 0.8, 'default': 0.3}

../../anaconda/envs/reco_full/lib/python3.6/ast.py:84: ValueError


```


hey @seanytak, I'm reviewing the unit test and there is an error with this one. Would you mind to take a look?

### In which platform does it happen?
<!--- Describe the platform where the issue is happening (use a list if needed) -->
<!--- For example: -->
<!--- * Azure Data Science Virtual Machine. -->
<!--- * Azure Databricks.  -->
<!--- * Other platforms.  -->

### How do we replicate the issue?
<!--- Please be specific as possible (use a list if needed). -->
<!--- For example: -->
<!--- * Create a conda environment for pyspark -->
<!--- * Run unit test `test_sar_pyspark.py` with `pytest -m 'spark'` -->
<!--- * ... -->

### Expected behavior (i.e. solution)
<!--- For example:  -->
<!--- * The tests for SAR PySpark should pass successfully. -->

### Other Comments


Changed files:
tests/unit/test_nni_utils.py, reco_utils/tuning/nni/ncf_utils.py

diff --git a/reco_utils/tuning/nni/ncf_utils.py b/reco_utils/tuning/nni/ncf_utils.py
index 5df48a40..f6a5a2f1 100644
--- a/reco_utils/tuning/nni/ncf_utils.py
+++ b/reco_utils/tuning/nni/ncf_utils.py
@@ -5,17 +5,17 @@ import pandas as pd
 
 
 def compute_test_results(model, train, test, rating_metrics, ranking_metrics):
-	"""Compute the test results using a trained NCF model.
+    """Compute the test results using a trained NCF model.
     
     Args:
-    	model (obj): TF model.
+        model (obj): TF model.
         train (pd.DataFrame): Train set.
         test (pd.DataFrame): Test set.
         rating_metrics (list): List of rating metrics.
         ranking_metrics (list): List of ranking metrics.
         
     Returns:
-    	dict: Test results. 
+        dict: Test results. 
     
     """
     test_results = {}
@@ -51,13 +51,13 @@ def compute_test_results(model, train, test, rating_metrics, ranking_metrics):
   
   
 def combine_metrics_dicts(*metrics):
-	"""Combine metrics from dicts.
+    """Combine metrics from dicts.
     
     Args:
-    	metrics (dict): Metrics
+        metrics (dict): Metrics
         
     Returns:
-    	pd.DataFrame: Dataframe with metrics combined.    
+        pd.DataFrame: Dataframe with metrics combined.    
     """
     df = pd.DataFrame(metrics[0], index=[0])
     for metric in metrics[1:]:
diff --git a/tests/unit/test_nni_utils.py b/tests/unit/test_nni_utils.py
index b33c9909..6170a5fb 100644
--- a/tests/unit/test_nni_utils.py
+++ b/tests/unit/test_nni_utils.py
@@ -166,13 +166,14 @@ def test_check_metrics_written_timeout():
 @pytest.mark.skipif(sys.platform == "win32", reason="nni not installable on windows")
 def test_get_trials():
     with TemporaryDirectory() as tmp_dir1, TemporaryDirectory() as tmp_dir2:
+        
         mock_trials = [
             {
-                "finalMetricData": [{"data": '{"rmse":0.8,"default":0.3}'}],
+                "finalMetricData":[{"data":"\\"{\\\\\\"rmse\\\\\\": 0.8, \\\\\\"default\\\\\\": 0.3}\\""}],
                 "logPath": "file://localhost:{}".format(tmp_dir1),
             },
             {
-                "finalMetricData": [{"data": '{"rmse":0.9,"default":0.2}'}],
+                "finalMetricData":[{"data":"\\"{\\\\\\"rmse\\\\\\": 0.9, \\\\\\"default\\\\\\": 0.2}\\""}],
                 "logPath": "file://localhost:{}".format(tmp_dir2),
             },
         ]