From 904a2b957df3e4a3ad4540626daede6e81d43e4a Mon Sep 17 00:00:00 2001 From: Ramesh RV Date: Mon, 8 Oct 2018 16:09:19 +0530 Subject: [PATCH] New feature (Finding occurance) --- README.rst | 23 ++++++++++ nested_lookup/__init__.py | 3 +- nested_lookup/nested_lookup.py | 55 ++++++++++++++++++++++++ setup.py | 2 +- test_nested_loopkup.py | 78 +++++++++++++++++++++++++++++++++- 5 files changed, 158 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 5afc5ca..fff6165 100644 --- a/README.rst +++ b/README.rst @@ -8,6 +8,7 @@ A small Python library which enables: #. key lookups on deeply nested documents. #. fetching all keys from a nested dictionary. +#. get the number of occurances of a key/value from a nested dictionary Documents may be built out of dictionaries (dicts) and/or lists. @@ -50,6 +51,14 @@ quick tutorial >>> get_all_keys(document) ['taco', 'salsa', 'burrito', 'taco'] + >>> from nested_lookup import get_occurance_of_key, get_occurance_of_value + + >>> get_occurance_of_key(document, key='taco') + 2 + + >>> get_occurance_of_value(document, value='42') + 1 + longer tutorial =============== @@ -93,6 +102,20 @@ To get a list of every nested key in a document, run this: ['name', 'email_address', 'other', 'secondary_email', 'EMAIL_RECOVERY', 'email_address'] +To get the number of occurance of the given key/value + +.. code-block:: python + + from nested_lookup import get_occurance_of_key, get_occurance_of_value + + no_of_key_occurance = get_occurance_of_key(my_document, key='email_address') + + print(no_of_key_occurance) # result => 2 + + no_of_value_occurance = get_occurance_of_value(my_document, value='test2@example.com') + + print(no_of_value_occurance) # result => 1 + Next, we could act `wild` and find all the email addresses like this: .. code-block:: python diff --git a/nested_lookup/__init__.py b/nested_lookup/__init__.py index 367b245..1da6552 100644 --- a/nested_lookup/__init__.py +++ b/nested_lookup/__init__.py @@ -1 +1,2 @@ -from .nested_lookup import nested_lookup, get_all_keys +from .nested_lookup import nested_lookup, get_all_keys, get_occurance_of_key,\ + get_occurance_of_value diff --git a/nested_lookup/nested_lookup.py b/nested_lookup/nested_lookup.py index 17de3fd..1e22531 100644 --- a/nested_lookup/nested_lookup.py +++ b/nested_lookup/nested_lookup.py @@ -62,3 +62,58 @@ def get_all_keys(dictionary): recrusion(dictionary=dictionary) return result_list + + +def get_occurance_of_key(dictionary, key): + """ + Method to get occurance of a key in a nested dictionary + + Args: + dictionary: Nested dictionary + key: Key to search for the occurances + Return: + Number of occurance (Integer) + """ + return _get_occurrence(dictionary=dictionary, item='key', keyword=key) + + +def get_occurance_of_value(dictionary, value): + """ + Method to get occurance of a value in a nested dictionary + + Args: + dictionary: Nested dictionary + value: Value to search for the occurances + Return: + Number of occurance (Integer) + """ + return _get_occurrence(dictionary=dictionary, item='value', keyword=value) + + +def _get_occurrence(dictionary, item, keyword): + """ + Method to get occurance of a key or value in a nested dictionary + + Args: + dictionary: Nested dictionary + item: Mostly (key or value) + keyword: key word to find occurance + Return: + Number of occurance of the given keyword in the dict + """ + occurance = [0] + + def recrusion(dictionary): + if item == 'key': + occurance[0] += 1 if dictionary.get(keyword) else 0 + elif keyword in dictionary.values(): + occurance[0] += dictionary.values().count(keyword) + for key, value in iteritems(dictionary): + if isinstance(value, dict): + recrusion(dictionary=value) + elif isinstance(value, list): + for list_items in value: + recrusion(dictionary=list_items) + + recrusion(dictionary=dictionary) + return occurance[0] diff --git a/setup.py b/setup.py index 15bba6b..36955bf 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ with open('requirements.txt', 'r') as f: setup( name = 'nested-lookup', - version = '0.1.6', + version = '0.1.7', description = 'lookup a key in a deeply nested document of dicts and lists', keywords = 'nested document dictionary dict list lookup schema json xml yaml', long_description = open('README.rst').read(), diff --git a/test_nested_loopkup.py b/test_nested_loopkup.py index d02e9dc..447c56f 100644 --- a/test_nested_loopkup.py +++ b/test_nested_loopkup.py @@ -1,6 +1,7 @@ from unittest import TestCase -from nested_lookup import nested_lookup, get_all_keys +from nested_lookup import nested_lookup, get_all_keys, get_occurance_of_key,\ + get_occurance_of_value class TestNestedLookup(TestCase): @@ -160,5 +161,80 @@ class TestGetAllKeys(TestCase): self.assertIn(key, result) +class TestGetOccurance(TestCase): + def setUp(self): + self.sample1 = { + "build_version": { + "model_name": "MacBook Pro", + "build_version": { + "processor_name": "Intel Core i7", + "processor_speed": "2.7 GHz", + "core_details": { + "build_version": "4", + "l2_cache(per_core)": "256 KB" + } + }, + "number_of_cores": "4", + "memory": "256 KB", + }, + "os_details": { + "product_version": "10.13.6", + "build_version": "17G65" + }, + "name": "Test", + "date": "YYYY-MM-DD HH:MM:SS" + } + self.sample2 = { + "hardware_details": { + "model_name": "MacBook Pro", + "processor_details": [{ + "processor_name": "4", + "processor_speed": "2.7 GHz", + "core_details": { + "total_numberof_cores": "4", + "l2_cache(per_core)": "256 KB" + } + }], + "total_number_of_cores": "4", + "memory": "16 GB", + } + } + self.sample3 = { + "hardware_details": { + "model_name": "MacBook Pro", + "processor_details": [ + { + "total_number_of_cores": "4", + "processor_speed": "2.7 GHz", + }, + { + "total_number_of_cores": "4", + "l2_cache(per_core)": "256 KB" + } + ], + "total_number_of_cores": "4", + "memory": "16 GB", + } + } + + def test_sample_data1(self): + result = get_occurance_of_key(self.sample1, 'build_version') + self.assertEqual(4, result) + result = get_occurance_of_value(self.sample1, '256 KB') + self.assertEqual(2, result) + + def test_sample_data2(self): + result = get_occurance_of_key(self.sample2, 'core_details') + self.assertEqual(1, result) + result = get_occurance_of_value(self.sample2, '4') + self.assertEqual(3, result) + + def test_sample_data3(self): + result = get_occurance_of_key(self.sample3, 'total_number_of_cores') + self.assertEqual(3, result) + result = get_occurance_of_value(self.sample3, '4') + self.assertEqual(3, result) + + if __name__ == "__main__": pass