Repository: EdinburghGenomics/EGCG-Core

Issue:
Dot-notated dict querying
We implement this quite a lot in multiple places, so can add this as a common function:

```python
>>> d = {'this': {'that': 'other'}}
>>> query_dict(d, 'this.that')
'other'
```

Discussion:

Patch:
diff --git a/egcg_core/util.py b/egcg_core/util.py
index d1719af..0bfb634 100644
--- a/egcg_core/util.py
+++ b/egcg_core/util.py
@@ -100,3 +100,22 @@ def move_dir(src_dir, dest_dir):
             dest_file = os.path.join(dest_dir, os.path.basename(src_file))
             shutil.move(fp, dest_file)
     return 0
+
+
+def query_dict(data, query_string):
+    """
+    Drill down into a dict using dot notation, e.g. query_dict({'this': {'that': 'other'}}, 'this.that'}).
+    :param dict data:
+    :param str query_string:
+    """
+    _data = data.copy()
+
+    for q in query_string.split('.'):
+        d = _data.get(q)
+        if d is None:
+            return None
+
+        else:
+            _data = d
+
+    return _data


Test patch:
diff --git a/tests/test_util.py b/tests/test_util.py
index 7881fc3..fe703e8 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -74,7 +74,6 @@ class TestMoveDir(TestEGCG):
 
     def setUp(self):
         self.test_dir = join(self.assets_path, 'move_dir')
-        makedirs(join(self.test_dir, 'from'), exist_ok=True)
         makedirs(join(self.test_dir, 'from', 'subdir'), exist_ok=True)
         self._create_test_file(join(self.test_dir, 'from', 'ftest.txt'))
         self._create_test_file(join(self.test_dir, 'from', 'subdir', 'ftest.txt'))
@@ -83,7 +82,6 @@ class TestMoveDir(TestEGCG):
         self._create_test_file(join(self.test_dir, 'external', 'external.txt'), 'External file')
         symlink(join(self.test_dir, 'external', 'external.txt'), join(self.test_dir, 'from', 'external_renamed.txt'))
 
-        makedirs(join(self.test_dir, 'exists'), exist_ok=True)
         makedirs(join(self.test_dir, 'exists', 'subdir'), exist_ok=True)
         self._create_test_file(join(self.test_dir, 'exists', 'subdir', 'ftest.txt'), 'another file')
         self._create_test_file(join(self.test_dir, 'exists', 'ftest.txt'), 'another file')
@@ -127,3 +125,10 @@ class TestMoveDir(TestEGCG):
         assert util.find_file(to, 'ftest.txt')
         assert md5_from1 == self._md5(join(to, 'ftest.txt'))
         assert md5_from2 == self._md5(join(to, 'subdir', 'ftest.txt'))
+
+
+def test_query_dict():
+    data = {'this': {'that': 'other'}}
+    assert util.query_dict(data, 'this') == {'that': 'other'}
+    assert util.query_dict(data, 'this.that') == 'other'
+    assert util.query_dict(data, 'nonexistent') is None